Android 4.X 系統載入 so 失敗的原因分析

來源:互聯網
上載者:User

標籤:.com   新解   代碼   pat   blog   網上   消失   java   記憶體   

1 so 載入過程

so 載入的過程可以參考小米的系統工程師的文章loadLibrary動態庫載入過程分析

2 問題分析2.1 問題

年前項目裡新加了一個 so庫,但發現native 方法的找不到的 crash 好多,好些都是報了java.lang.unsatisfiedlinkerror native method not found,而且基本上是出現在4.x的系統裡,特別是 4.4,4.2的系統。在網路上搜尋相關的可能導致到這個問題的原因:

  • so 檔案沒有在對應架構的目錄裡找到;
  • 方法名有錯誤;

    2.2 分析1

    我們最開始是懷疑應用在安裝時沒有正確解壓出對應的so檔案到相應目錄,因此加了相應統計來看發生crash的手機是否是因為找不到對應的 so檔案導致的;但統計資料發現這些手機裡都可以找到對應架構的 so檔案,因此就排除了不存在so檔案導致的 crash;

2.3 分析2

我們同事以前有發現在Android 4.x系統裡,如果so 檔案是在應用啟動時載入的,但使用時機卻在後面的時間點,so載入進手機的記憶體可能會被系統由於資源緊張而回收掉,這種情況下,可以通過重新載入一次 so檔案來減少相關的 crash,這種方法 fix了某個量很高的 so 相關的crash。但我們的 socrash 明顯是不屬於這種情況的,因為我們是通過 System.load() 方法載入完 so檔案後,就調用相關的方法,這時記憶體肯定是還在的。在分析了一系列可能的原因後,懷疑這個crash 是因為應用安裝時解壓出來的 so檔案是損壞的,因此我們嘗試在第一次發生這個crash時,將這個crash catch住,然後在 catch塊將原來目錄下的 so檔案刪除掉,並重新從應用的安裝目錄解壓出對應的so檔案放到原來的目錄,並加了相關的統計來驗證。so的載入用了 Relinkder。相關的簡化版本代碼如下:

relinker.loadLibrary(getApplicationContext(), "so_name");try{    // call native method} catch(UnsatisfiedLinkError e) {    //some stats     String 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 的解決方案後,我們的 sojava.lang.unsatisfiedlinkerror native method not found 大部分消失了。理論上使用過一次重新解壓so 檔案後,這個使用者在下一次升級前都應該不會再發生了類似的 crash了,但我們的統計資料發現,有些使用者每一次啟動都需要進入catch塊來避免crash,而每次都可以通過 reload來正常使用我們的應用,這至今還是個迷,還沒有想明白是什麼情況會導致這個問題?手機的儲存有問題?但其他的so又沒有這個問題。希望如果有同行解決過類似的問題的,指點一下。

3 總結

Android 4.X 系統載入 so 後,出現 java.lang.unsatisfiedlinkerror native method not foundcrash的原因除了網上所說的 不存在這個so 和 方法名有問題(商用的應用應該不會有這個問題的)外,還有兩個原因:

  • so 載入進系統的記憶體被系統由於資緊張而回收了,這種情況下直接再load一下 so 檔案就可以解決大部分;
  • so 檔案有問題,這種情況下,可以通過重新從應用安裝目錄解壓出對應的 so 檔案並重新載入來解決大部分;

這兩種方法不能保證可以100%解決問題,但可以減少大部分問題(90%);

Android 4.X 系統載入 so 失敗的原因分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.