1. 程式人生 > >【MultiDex.install引發低端機ANR】為什麽64K?字節碼決定

【MultiDex.install引發低端機ANR】為什麽64K?字節碼決定

space 線程 java ext contex 進程 就會 load 加載

問題:低端機首次啟動時間久,極大概率觸發ANR

分析:

  1. 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?字節碼決定