在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升级后不能用。二.那如何解决这个鬼问题呢?
我纯粹是为了调试方便,所以参考google的链接
https://source.android.com/devices/tech/config/namespaces_libraries应用可以调用/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 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。