Android 4.X 系统加载 so 失败的原因分析
1 so 加載過程
so 加載的過程可以參考小米的系統(tǒng)工程師的文章loadLibrary動態(tài)庫加載過程分析
2 問題分析
2.1 問題
年前項目里新加了一個 so庫,但發(fā)現(xiàn)native 方法的找不到的 crash 好多,好些都是報了java.lang.unsatisfiedlinkerror native method not found,而且基本上是出現(xiàn)在4.x的系統(tǒng)里,特別是 4.4,4.2的系統(tǒng)。在網(wǎng)絡(luò)上搜索相關(guān)的可能導(dǎo)致到這個問題的原因:
- so 文件沒有在對應(yīng)架構(gòu)的目錄里找到;
方法名有錯誤;
2.2 分析1
我們最開始是懷疑應(yīng)用在安裝時沒有正確解壓出對應(yīng)的so文件到相應(yīng)目錄,因此加了相應(yīng)統(tǒng)計來看發(fā)生crash的手機(jī)是否是因為找不到對應(yīng)的 so文件導(dǎo)致的;但統(tǒng)計數(shù)據(jù)發(fā)現(xiàn)這些手機(jī)里都可以找到對應(yīng)架構(gòu)的 so文件,因此就排除了不存在so文件導(dǎo)致的 crash;
2.3 分析2
我們同事以前有發(fā)現(xiàn)在Android 4.x系統(tǒng)里,如果so 文件是在應(yīng)用啟動時加載的,但使用時機(jī)卻在后面的時間點(diǎn),so加載進(jìn)手機(jī)的內(nèi)存可能會被系統(tǒng)由于資源緊張而回收掉,這種情況下,可以通過重新加載一次 so文件來減少相關(guān)的 crash,這種方法 fix了某個量很高的 so 相關(guān)的crash。但我們的 so的 crash 明顯是不屬于這種情況的,因為我們是通過 System.load() 方法加載完 so文件后,就調(diào)用相關(guān)的方法,這時內(nèi)存肯定是還在的。在分析了一系列可能的原因后,懷疑這個crash 是因為應(yīng)用安裝時解壓出來的 so文件是損壞的,因此我們嘗試在第一次發(fā)生這個crash時,將這個crash catch住,然后在 catch塊將原來目錄下的 so文件刪除掉,并重新從應(yīng)用的安裝目錄解壓出對應(yīng)的so文件放到原來的目錄,并加了相關(guān)的統(tǒng)計來驗證。so的加載用了 Relinkder。相關(guān)的簡化版本代碼如下:
relinker.loadLibrary(getApplicationContext(), "so_name"); try{// call native method } catch(UnsatisfiedLinkError e) {//some statsString library = "so_name";String libName = System.mapLibraryName(library);File workaroundLibDir = getApplicationContext().getDir("lib", Context.MODE_PRIVATE);File workaroundLibFile = new File(workaroundLibDir, libName);workaroundLibFile.delete();apkLibraryInstaller.installLibrary(getApplicationContext(), supportedAbis(), libName, workaroundLibFile, relinker);System.load(workaroundLibFile.getAbsolutePath());//call native method// some stats }2.4 分析3
在使用的 2.3 的解決方法后,我們的 so 的 java.lang.unsatisfiedlinkerror native method not found 大部分消失了。理論上使用過一次重新解壓so 文件后,這個用戶在下一次升級前都應(yīng)該不會再發(fā)生了類似的 crash了,但我們的統(tǒng)計數(shù)據(jù)發(fā)現(xiàn),有些用戶每一次啟動都需要進(jìn)入catch塊來避免crash,而每次都可以通過 reload來正常使用我們的應(yīng)用,這至今還是個迷,還沒有想明白是什么情況會導(dǎo)致這個問題?手機(jī)的存儲有問題?但其他的so又沒有這個問題。希望如果有同行解決過類似的問題的,指點(diǎn)一下。
3 總結(jié)
Android 4.X 系統(tǒng)加載 so 后,出現(xiàn) java.lang.unsatisfiedlinkerror native method not found的crash的原因除了網(wǎng)上所說的 不存在這個so 和 方法名有問題(商用的應(yīng)用應(yīng)該不會有這個問題的)外,還有兩個原因:
- so 加載進(jìn)系統(tǒng)的內(nèi)存被系統(tǒng)由于資緊張而回收了,這種情況下直接再load一下 so 文件就可以解決大部分;
- so 文件有問題,這種情況下,可以通過重新從應(yīng)用安裝目錄解壓出對應(yīng)的 so 文件并重新加載來解決大部分;
這兩種方法不能保證可以100%解決問題,但可以減少大部分問題(90%);
轉(zhuǎn)載于:https://www.cnblogs.com/WoodJim/p/8468865.html
總結(jié)
以上是生活随笔為你收集整理的Android 4.X 系统加载 so 失败的原因分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php layui 框架,Thinkph
- 下一篇: android触摸指纹会触发按键功能,A