Android push到/system/app下,導致找不到so文件,拋出java.lang.UnsatisfiedLinkError的原因分析和解決方案

首先,我們來看一份真實案例的輸出日誌:

AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.cmccpoc, PID: 2708
AndroidRuntime: java.lang.UnsatisfiedLinkError: Couldn't load airtalkee from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/system/app/POCM3A.apk",  zip file "/data/data/com.cmccpoc/code_cache/secondary-dexes/POCM3A.apk.classes2.zip"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null
AndroidRuntime:     at java.lang.Runtime.loadLibrary(Runtime.java:358)
AndroidRuntime:     at java.lang.System.loadLibrary(System.java:526)
AndroidRuntime:     at com.airtalkee.sdk.engine.AirNative.<clinit>(Unknown Source)
AndroidRuntime:     at com.airtalkee.sdk.engine.AirEngine.serviceTraceMode(Unknown Source)
AndroidRuntime:     at com.airtalkee.sdk.controller.AccountController.traceMode(Unknown Source)
AndroidRuntime:     at com.airtalkee.sdk.AirtalkeeAccount.AirTalkeeConfigTrace(Unknown Source)
AndroidRuntime:     at com.cmccpoc.application.MainApplication.onCreate(MainApplication.java:38)
AndroidRuntime:     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
AndroidRuntime:     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4422)
AndroidRuntime:     at android.app.ActivityThread.access$1500(ActivityThread.java:138)
AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1259)
AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
AndroidRuntime:     at android.os.Looper.loop(Looper.java:136)
AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5095)
AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

 

我們首先來分析一下原因:
1、同樣的包,同樣的so,通過install就能正常運行
   我們去掉在應用的manifest.xml中添加的android:sharedUserId="android.uid.system",然後重新編譯打包,使用adb install直接安裝,是不是很神奇,能夠正常運行。
2、迴歸主題
   我們是要解決在app是系統應用的情況下,也就是manifest.xml中添加的android:sharedUserId="android.uid.system",
   使用push將包推到/system/app下的情況(這裏也要特別說一下,Android5.0之後的Android,最好將apk文件push到/system/priv-app目錄)。
   步驟如下,編譯打包,然後adb push xxx.apk /system/app,重啓,來了,崩潰了,逮住日誌看一下,從日誌中可以看出拋出java.lang.UnsatisfiedLinkError,
   從nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null
   這句話可以看出,它從/vendor/lib, /system/lib這兩個路徑去找so文件,結果沒有找到(findLibrary returned null)。
   這又是爲什麼呀?
   原因是/system/app下面的APK成爲系統級app時,包含SO文件,app默認加載so庫的路徑就會變成/system/lib,而system/lib卻是隻讀的,導致so庫無法正常解壓不會自動安裝,
   需要手動把so文件push 到 "/system/lib"目錄下面。
   
3、解決方案
   知道了原因,於是就開始準備解決方案,有兩種解決方案:
   A、將apk中的so文件手動push到"/system/lib"
   B、思路是將apk中的so庫複製到/data/data/應用包名/lib的安裝目錄中,再通過反射更改app加載so庫的路徑
   以上兩種我都試過,是OK的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章