1. 程式人生 > >Android Multidex導致的App啟動緩慢

Android Multidex導致的App啟動緩慢

Android社群中多次說到了dex包的65536方法數限制,現在針對這個問題的解決方法是dex分包(Multidexing)。雖然這是google提出的一個很好的解決辦法,但是我注意到了它對App的啟動速度影響很嚴重(這個問題現在還沒有被Android社群所重視)。所以我寫下了這篇文章,寫給那些想實現dex分包但是不知道它的這個缺點或者已經實現了dex分包但是想看看它效能的開發者。

背景

簡單來說,構建Android應用時這樣一個流程:Java程式碼=>.class檔案(與依賴庫)=>獨立的.dex檔案。這個.dex檔案最後與資原始檔一起打包成.apk檔案,這就是你最後從應用商店下載下來的安裝檔案。

對編譯過程的一個限制就是在dex檔案中系統允許的方法總數最多為65536。早期的Android開發者通過混淆來減少不必要的程式碼,從而避免方法數超過限制的問題。然而混淆在這方面能做到的事情比較有限,而且它只是延緩了方法數量過限的時間,並沒有根治。所以後來Google在support library裡面出了一個解決方案:dex分包(Multidex),這個方案可以很方便地處理方法數超過限制的問題,但是就如同我之前所說,它會極大地延緩App的啟動速度。

使用Multidex

Multidex現在是一個成熟的、文件豐富的工具。

NoClassDefFoundError?!

當你在專案中使用了multidex的時候,你的app可能會產生java.lang.NoClassDefFoundError

異常。這意味著你的app在啟動的時候沒有找到含有指定類的class檔案。Android的Gradle外掛首先需要SDK build tools 21.1及以上才支援multidex,它會在混淆工程之後列出一個主dex檔案中包含的類的清單([buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt)。但這裡面可能沒有包含所有在App啟動時需要載入的類,這時啟動App就會丟擲這個異常。

如何解決?

要解決這個問題,你要列出一份啟動App時需要載入的類的清單,並告訴編譯器這些類要保留在主dex檔案中。你可以這麼做:

  • 在工程資料夾下建立一個multidex.keep
    檔案
  • java.lang.NoClassDefFoundError異常中報出的類列到multidex.keep中。(不要修改maindexlist.txt,這個檔案每次都會重新生成,改動無效)
  • 在使用混淆的模組的gradle指令碼中天下如下程式碼,它會每次在編譯的時候將multidex.keep檔案中的內容新增到`maindexlist.txt"中。

[程式碼]java程式碼:

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 android.applicationVariants.all { variant -> task "fix${variant.name.capitalize()}MainDexClassList" << { logger.info "Fixing main dex keep file for $variant.name" File keepFile = new File("$buildDir/intermediates/multi-dex/$variant.buildType.name/maindexlist.txt") keepFile.withWriterAppend { w -> // Get a reader for the input file w.append('\n') new File("${projectDir}/multidex.keep").withReader { r -> // And write data from the input into the output w << r << '\n' } logger.info "Updated main dex keep file for ${keepFile.getAbsolutePath()}\n$keepFile.text" } } } tasks.whenTaskAdded { task -> android.applicationVariants.all { variant -> if (task.name == "create${variant.name.capitalize()}MainDexClassList") { task.finalizedBy "fix${variant.name.capitalize()}MainDexClassList" } } }

Multidex對應用啟動速度造成的影響。

如果你使用了multidex,那麼你需要注意它可能會加長App的啟動速度。我們通過追蹤App的啟動時間(從點選icon到所有的圖示被下載、顯示的時間)。當使用multidex後,4.4及以下的系統啟動時間會加長大約15%,你可以在Carlos Sessa的這篇文章中瞭解到更多資訊。

由於5.0以上的Android系統採用了ART執行時,它本身就支援multidex的載入,所以5.0以上系統影響較小。但是5.0以下的系統將會在載入主dex之外的類時會有比較明顯的延遲。

解決multidex帶來的啟動時間影響

在App啟動到所有圖片載入到螢幕上之間的這段時間內,有很多類既沒有被混淆,也不在主dex檔案中。我們要怎麼知道哪些類已經被App載入了呢?

相關推薦

Android Multidex導致App啟動緩慢

Android社群中多次說到了dex包的65536方法數限制,現在針對這個問題的解決方法是dex分包(Multidexing)。雖然這是google提出的一個很好的解決辦法,但是我注意到了它對App的啟動速度影響很嚴重(這個問題現在還沒有被Android社群所重視)。所以我寫下了這篇文章,寫給那些想實

Android UI優化— App啟動優化

黑白屏產生的原因和解決辦法 黑白屏產生的原因 1、還沒載入到佈局檔案,就已經顯示了window視窗背景 2、黑屏白屏就是window視窗背景 容易產生黑白屏的地方 1、Activity的onCreate()中 @Override pro

Android UI優化—App啟動流程和啟動模式

Android 理論基礎 1、每一個Android App都執行在一個單獨的程序中 2、Android App由很多不同元件組成,這些元件還可以啟動其他App的元件 3、一個程序裡面只有一個主執行緒 4、程序在其需要的時候被啟動 基於上述共識,我們先來分析Android系統的啟動流程

解決AVAST防毒軟體導致系統啟動緩慢的問題

1. 前言     很多年前,從大學老師和同學那裡得知有個功能很強的免費防毒軟體,名字是AVAST。從AVAST4就從事用這個軟體了,曾經有一段時期,軟體程式版本更新很慢,一直在用AVAST4。 2.軟體使用經驗     後來終於等到了AVAST5,於是立馬升級,體驗更強

Android AMS(三) App啟動過程之onResume

在Android AMS(二) App啟動過程之onCreate中我們講了onCreate的呼叫流程,這篇我們接著分析onResume的流程 ActivityThread.java-->handleLaunchActivity()中呼叫performLaunchActivity()走到ac

Android AMS(二) App啟動過程之onCreate

在Android AMS(一) App啟動過程之Task,程序建立流程中我們講到了Process.start,在這裡會通過zygote啟動程序,通過反射呼叫ActivityThread的main函式 public static void main(String[] args) {

Android 通過一個app 啟動另一個app

PackageManager packageManager = getPackageManager(); String packname="";//此處為包名 if (checkPackInfo(packname)) {//檢查是否有要開啟的app Intent intent = packag

深入淺出Android中的App啟動流程分析

App啟動是指使用者點選手機桌面的app對應的icon開始,所以我們需要明白幾點基礎知識: 1.桌面也是一個Activity叫Launcher.java 2.在桌面點選icon啟動app跟在app內部啟動另一個Activity是一樣的都是呼叫startAct

Android Studio 改變app啟動頁面

<activity android:name=".MainActivity"> </activity> <activity android:name=".welcome

android 實現一個app啟動另一個app的service服務

首先我們建立兩個android 工程 這裡我們稱被啟動的app為甲,啟動被啟動的app為已,首先我們在甲 app類中new一個Myservice類 在類的onCreate函式中我們寫一個匿名執行緒 public class MyService exte

Instant Run 的操作影響到了代碼,導致Android App啟動閃退的問題

content 們的 發現 clas clear ons ola vertica andro 轉自yuhc163原文android啟動應用java.lang.NoClassDefFoundError: Class not found using the boot clas

Android MultiDex初次啟動APP優化

在開始文章之前,強烈建議不熟悉MultiDex坑點的童鞋看兩篇文章: 簡單來說,安裝完成並初次啟動APP的時候,5.0以下某些低端機會出現ANR或者長時間卡頓不進入引導頁,而罪魁禍首是MultiDex.install(Context context)的de

Android 中如何從一個App啟動另外一個App(如啟動支付界面、啟動地圖界面、應用商場下載App等場景)

!= oid 等等 信息 fault next -a return 5.1   假定兩個App,分別是A和B,當A運行某個功能需要啟動B,一種是啟動B應用,一種直接進入B的某個Activity。搜了很多資料,沒有一個完整的。下面就A--Android5.1.1、B--And

如何找到Android app啟動activity和頁面元素信息

dump ref adg 按鈕 配置環境變量 好的 too 啟動app ace 在實施app自動化的時候,我們需要知道app 的啟動activity和頁面元素信息,以此啟動app和定位頁面元素,那麽如何在沒有源碼的情況下找打他們呢?當然是有好的工具啦,有Android sd

android App啟動白屏

顯示 draw 出現 com pan code 文件中 class 但是 app啟動的時候在啟動也顯示之前會出現白屏或黑屏的情況。 主要是因為視圖沒有及時填充上造成的,解決方式如下: 在style中添加以下代碼: <style name="SplashTheme"

Android APP啟動頁面動態加載全部權限

uil ted spl count 文件中 nta proc contact 代碼 一、寫在前面 6.0以上動態加載權限加載的是,需要用戶手動賦予的權限( Dangerous Permissions),只有這些,其他權限不用加載 所屬權限組 權限日歷 READ_CALEND

【轉載】Android Bug分析系列:第三方平臺安裝app啟動後,home鍵回到桌面後點擊app啟動時會再次啟動入口類bug的原因剖析

特殊 返回 androidm android系統 圖片 管理 相關 OS 簡便 前言   前些天,測試MM發現了一個比較奇怪的bug。   具體表現是:   1、將app包通過電腦QQ傳送到手機QQ上面,點擊安裝,安裝後選擇打開app (此間的應用邏輯應該是要觸發 【閃屏頁

Android app啟動activity並調用onCreate()方法時都默默地幹了什麽?

AR 其中 保存狀態 位置 mod con 會同 語句 Go Android app啟動activity並調用onCreate() 方法時都默默地幹了什麽? 在AndroidManifest.xml文件中的<intent-filter>元素

APP性能(Android手機):APP啟動時間

過濾 app性能測試 策略 AD .com oid image conn 保存 1 APP性能測試 1.1 啟動時間 1.1.1 執行 1.1.2 策略 1.1.3 工具adb 連接模擬器:adb co

Android App啟動簡單流程

Launcher響應我們產生的點選事件後,實際上就是啟動一個新的Activity。 Launcher將會通過App的快捷方式(ShortcutInfo)得到應用的Intent,並通過這個Intent啟動應用的“MainActivity”,從而啟動應用。 Launcher通過Binder通