項目最近線上開始報一個異常:SimpleDraweeView was not initialized。問題很快就定位到了,是咱們使用了fresco,裏面SimpleDraweeView有個靜態成員:sDraweeControllerBuilderSupplier未被初始化致使:
也就是在使用SimpleDraweeView以前須要有個初始化,官方文檔也有說明須要先調用下Fresco.initialize方法。java
而這個初始化咱們在Application的onCreate裏面就調用了,爲啥還會報這個錯誤呢?android
首先懷疑類是否是被卸載了,根據這個異常的堆棧是發生在首頁,也就是在Application的onCreate後進首頁前類被卸載,一個類被卸載有幾種狀況,好比不存在該類的實例,類不存在引用等。java裏面能夠加啓動參數來增長類卸載回調,但android裏面就不太方便了。爲了驗證這個問題,在Application的onCreate裏面引用一個SimpleDraweeView對象,發現仍是崩潰了。微信
崩潰雖然是同一個,但也發現了更多問題,新增的引用一個SimpleDraweeView對象代碼沒有執行,同時發現Application的onCreate裏面的debug log也沒有輸出,這就納悶了,難道Application的onCreate也會不被執行?經過翻閱源碼未發現attachBaseContext後面不執行onCreate的狀況。ide
經過增長log發現onCreate執行在中間某一步被return掉了,而這個條件判斷是當前進程是否是主進程的一個條件判斷。函數
這樣問題就清晰了,原來是Fresco.initialize方法雖然寫在onCreate裏面,但在這個機器上面onCreate執行在判斷主進程的條件上面返回了,致使後面代碼沒有執行,大概是下面這個意思:測試
而getProcess實現是這樣的:
優化
相信這也是不少應用的作法,由於程序裏面存在多進程,須要根據不一樣的進程在Application的onCreate裏面作不一樣的事情,因此就有相似這樣的代碼來判斷進程類型。結合上面的代碼,也就是說咱們判斷進程的函數出現了問題,本應該是MAIN進程,卻返回了是OTHER,結果致使代碼提早返回。而出現這種錯誤的緣由就是getRunningAppProcesses函數沒有可以正確返回。經過增長調試日誌確實發現偶爾這個函數不會返回當前程序進程。ui
經過反覆測試,發現一些規律:在Dalvik環境下面須要作multidex,正常啓動getRunningAppProcesses返回沒有問題,當第一次啓動dex作優化過久致使anr的時候,容易出現沒有返回當前程序進程,這個問題在oppo find7 4.3系統上面很容易復現。spa
試着搜了下,發現還真有這種說法:debug
https://stackoverflow.com/que...
解決辦法就是在getRunningAppProcesses判斷不許的時候,增長一種方法來繼續判斷,該方法兼容到4.0沒有問題。大概代碼以下:
具體緣由就不細究了,早期系統版本的問題,也不肯定是否是跟廠家修改有關係。寫這篇文章但願你們少走坑,多點時間陪陪家人~
歡迎關注微信公衆號:安卓之美