1. 程式人生 > >Android 7.0呼叫第三方庫出現載入失敗的問題

Android 7.0呼叫第三方庫出現載入失敗的問題

在Android7.0 ,自己編譯的APK放到系統裡,呼叫第三方庫沒有問題,但是通過SD卡點選apk檔案安裝,就出現

java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib64/libxxx.so" needed or dlopened by "/system/lib64/libnativeloader.so" is not accessible for the namespace "classloader-namespace"經歷了幾天的調查,發現http://www.jianshu.com/p/4be3d1dafbec文章寫的情況跟自己遇到的十分相似

一.那為啥剛刷機時APK可以用,Install這個apk後就不能用了呢?

這個apk可是系統許可權的喲,就是apk的清單AndroidManifest中有下面一句
android:sharedUserId="android.uid.system"

正常來說,這種高階apk的permitted_paths是包含system/lib64的,從原始碼可以知道
/frameworks/base/core/java/android/app/LoadedApk.java

        //如果是系統apk並且沒有升級過
        final boolean isBundledApp = mApplicationInfo.isSystemApp()
                && !mApplicationInfo.isUpdatedSystemApp();

        String libraryPermittedPath = mDataDir;
        if (isBundledApp) {   //permitted_paths就增加system/lib64
            // This is necessary to grant bundled apps access to
            // libraries located in subdirectories of /system/lib
            libraryPermittedPath += File.pathSeparator +
                                    System.getProperty("java.library.path");
        }

看上面的註釋就知道啦,如果是系統apk並且沒有升級過的話,so庫的搜尋路徑就會增加一個system/lib64。我去,google搞啥呢,為什麼還要限定不能升級。
因為install -r來安裝apk就相當於升級,所以刷機時apk可以用,install升級後不能用。



二.那如何解決這個鬼問題呢?

應用可以呼叫/vendor/etc/public.libraries.txt和/system/etc/public.libraries.txt裡面的所有so庫,所以往這個檔案寫入自己希望被呼叫的so,這個庫就變成共用的了,任意應用就可以找到這個so庫了 總結: 1.Android N 不能直接呼叫系統的一些私有庫了,公用的庫都定義在public.libraries.txt裡面。 2.系統應用剛刷機是能夠呼叫system/lib64下的庫,但通過install升級該應用時,應用開啟會掛。因為升級後permitted_paths就不再包含system/lib64了。所以我們可以將apk要用到的庫名稱寫到public.libraries.txt中去解決快速除錯問題。 作者:九九叔 連結:http://www.jianshu.com/p/4be3d1dafbec 來源:簡書 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。