【MultiDex.install引發低端機ANR】為什麽64K?字節碼決定
問題:低端機首次啟動時間久,極大概率觸發ANR
分析:
- ANR是什麽?
- 現象:App上彈出提示框,告知用戶當前xxx未響應,用戶可選擇繼續等待或者Force Close;
- 官方解釋:Application Not responding,應用程序未響應,Android系統對於一些事件需要在一定的時間範圍內完成,如果超過預定時間能未能得到有效響應或者響應時間過長,都會造成ANR;
- 主線程執行啟動過程中,用戶UI操作,未在指定時間內被處理。
http://gityuan.com/2017/01/01/input-anr/
2. 啟動過程做了什麽?
該圖是進入項目代碼層面後,執行代碼的順序。
attachBaseContext: 可控制第一個步驟, 執行MultiDex.install()
首次啟動:Dalvik虛擬機對classes.dex執行dexopt操作,生成odex文件【超時】
非首次啟動:直接從cache讀取
https://juejin.im/entry/5705b2712e958a0057a5f735
3. 為什麽只有低端機會中招?
Android 5.0及以上版本:ART模式,預先編譯,app安裝之後進行預編譯(pre-compilation) ,如果這時候發現了classes(..N).dex文件的存在就會將他們最終合成為一個.oat的文件
Android 5.0以下版本:安裝時僅處理主dex,首次啟動時執行dexopt操作,處理附屬dex文件
4. MultiDex ?
Android官網:Davlik中限制了單個dex中可引用方法總數不能超過64K,超過就必須要拆分為多個dex。
拋出異常的出處,打包過程某方法:
延展:為什麽是64K?
- 代碼的終極走向是被編譯為機器碼,被機器執行
- 引用方法等會被存入索引表,索引字段存儲於機器,機器字節碼位數限制可建索引項數。dalvik bytecode
如方法引用索引,16位,64K=2^16。
https://source.android.com/devices/tech/dalvik/dalvik-bytecode
特別感謝:http://jayfeng.com/2016/03/10/%E7%94%B1Android-65K%E6%96%B9%E6%B3%95%E6%95%B0%E9%99%90%E5%88%B6%E5%BC%95%E5%8F%91%E7%9A%84%E6%80%9D%E8%80%83/
解決:
高端機型(java.vm.version>”2.0.0”表明虛擬機運行環境為ART):直接執行MultiDex.install();
低端機型:增加初始化界面,LoadResActivity中異步執行加載
特別註意的是:當activity到後臺時,輪詢不啟動異步執行
借用網上一張流程圖,基本說明如下:基本流程類似,啟動檢測時機略有區別,啟動過程單獨起進程檢測是否安裝過
【MultiDex.install引發低端機ANR】為什麽64K?字節碼決定