【走過巨坑】android studio對於jni調用及運行閃退無法載入庫的問題解決方案

來源:互聯網
上載者:User

標籤:

相信很多小夥伴都在android開發中遇到調用jni的各種巨坑,因為我們不得不在很多地方用到第三方庫so檔案,然而第三方官方通常都只會給出ADT環境下的整合方式,而Google親兒子android studio預設採用的卻是gradle方式,與ADT編輯的方式大不相同,那再andorid studio中如何匯入so檔案呢?

在android studio 中我們可能會用到jar包和so檔案的方式,對於jar包可能接觸更多,只需要我們把工程轉換為project顯示方式,開啟app下的libs檔案夾,匯入即可。隨後再添加jar包為我們的工程依賴即可。

好吧,樓主不想跑題。對於so檔案也非常簡單,只需要在app/src/main下面建立一個jniLibs,再把我們的第三方so檔案拷貝進去即可,需要重點注意的是,我們安卓一般有幾種CPU,而不再是以前的只有armv5,目前有7種。ARMv5,ARMv7 (從2010年起),x86 (從2011年起),MIPS (從2012年起),ARMv8,MIPS64和x86_64 (從2014年起),每一種都關聯著一個相應的ABI。在Android系統上,每一個CPU架構對應一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。而這些包的名字是不能隨便更改的。

而我們在開發中,應該儘可能的得到每一種ABI最佳化過的.so檔案,而不應該混合著使用,其實為每一種ABI提供對應的.so檔案其實也是SDK提供方應該做的,不過或許你不會這麼好運,也許你的SDK提供方就會像和樓主遇到的一樣,只給你提供一個armeabi方式的.so檔案,額,是的,你寫一個小demo測試SDK的功能可能是可用的,然後當你把你寫的demo引入到你的項目中後,你或許總能遇到這樣那樣的問題,比如,最常見的就是UnsatisfiedLinkError,當然你還可能遇到dlopen: failed以及其它各種形式的crash或者低下的效能。而你或許在有的手機上運行卻是不報任何錯誤的。比如樓主得到的第三方SDK,只提供了armeabi下的so檔案,樓主匯入到項目中後,(樓主專案之前支援了arm64-v8a等其他方式的ABI)使用相對版本老一點的手機運行,Ok,no problem!然而當用到小米系列的任何一款手機的時候,運行,直接Crash,原因在初始化的時候直接找不到某些.so檔案,導致無法使用System.loadLabray的方式載入,不知道遇上的小夥伴是怎麼解決的,不過就這麼一個問題,讓樓主和一些同樣的開發人員也是抓破了腦袋,樓主是知其原因,而不知其解決方案,這是最令人頭疼的。

下面是android studio的報錯資訊。

08-21 11:12:48.413 7971-7971/com.hkyc.shouxinteacher.ischool E/AndroidRuntime: FATAL EXCEPTION: main                                                                               Process: com.hkyc.shouxinteacher.ischool, PID: 7971                                                                               java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.hkyc.shouxinteacher.ischool-2/base.apk"],nativeLibraryDirectories=[/data/app/com.hkyc.shouxinteacher.ischool-2/lib/arm64, /vendor/lib64, /system/lib64]]] couldn‘t find "libgnustl_shared.so"                                                                                   at java.lang.Runtime.loadLibrary(Runtime.java:366)                                                                                   at java.lang.System.loadLibrary(System.java:988)                                                                                   at com.idtechinfo.shouxiner.App.onCreate(App.java:92)                                                                                   at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1012)                                                                                   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4580)                                                                                   at android.app.ActivityThread.access$1500(ActivityThread.java:154)                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1376)                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)                                                                                   at android.os.Looper.loop(Looper.java:135)                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5283)                                                                                   at java.lang.reflect.Method.invoke(Native Method)                                                                                   at java.lang.reflect.Method.invoke(Method.java:372)                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)

好吧,真真令人頭疼,樓主採用了各種解決方式都沒有解決,因為android studio預設是會把所有ABI支援都打包到apk的,由於樓主得到的第三方SDK並不全面,所以遇上這樣的奇葩問題也是難免。

那麼,到底如何解決呢?

樓主通過網上提供的一些解決辦法說,可以在gradle中添加配置如下:

 1 android { 2     ...  3     splits { 4         abi { 5             enable true 6             reset() 7             include ‘x86‘, ‘x86_64‘, ‘armeabi-v7a‘, ‘arm64-v8a‘ //select ABIs to build APKs for 8             universalApk true //generate an additional APK that contains all the ABIs 9         }10     }11 12     // map for the version code13     project.ext.versionCodes = [‘armeabi‘: 1, ‘armeabi-v7a‘: 2, ‘arm64-v8a‘: 3, ‘mips‘: 5, ‘mips64‘: 6, ‘x86‘: 8, ‘x86_64‘: 9]14 15     android.applicationVariants.all { variant ->16         // assign different version code for each output17         variant.outputs.each { output ->18             output.versionCodeOverride =19                     project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode20         }21     }22  }

 

可事實是:找不到包名!!到底什麼鬼?

 

樓主在各種碰壁後,希望大家不要再在這種低級問題上碰的頭破血流,樓主的解決方案是通過build.gradle設定讓apk打包只打包armeabi包下的.so檔案,

添加代碼為:

 1   2  3 android{ 4  5    ....... 6  7     defaultConfig { 8         ndk { 9             abiFilters ‘armeabi‘,‘x86‘10         }11     }12 }

 

當然,這樣雖然投機取巧在aremabi下的可以支援所有的CPU機型,但是無疑使用不到各種機型特定的效能最佳化,為了讓其不會閃退,樓主也只能暫時採用此類方法。如果大家有更好的方法,也希望能在評論區共用,謝謝。

 轉載請在醒目位置附上本文連結:http://www.cnblogs.com/liushilin/p/5792505.html

【走過巨坑】android studio對於jni調用及運行閃退無法載入庫的問題解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.