关于升级系统预装应用出现.so的异常(java.lang.UnsatisfiedLinkError)

最近在与方案商合作,需要在升级系统包中预装应用。刚刚装进去,就出问题了。打开视频播放的时候,直接崩溃。提示以下错误:

alvik.system.PathClassLoader[DexPathList[[zip file "/system/priv-app/video.apk"],nativeLibraryDirectories=[/system/lib/video, /system/priv-app/video.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib, /system/vendor/lib, /system/lib, /vendor/lib, /system/vendor/lib]]] couldn't find "libijkffmpeg.so"

这种错误分两种情况:

一、是应用预装至系统区,就是用户都不能卸载的情况。这种好处理,只需要按照错误提示,将丢失的.so包push至system/lib下面就行。我使用的是ijkplayer视频播放的。所以在github找到相应的.so包后。直接导入到system/lib下面。重启后,可以正常播放视频

 

二、预装至data/app下面。这种用户可以卸载。

 D/ListenSoundModel( 3635): Load libxxxjni 
 D/AndroidRuntime( 3635): Shutting down VM 
——— beginning of crash 
E/AndroidRuntime( 3635): FATAL EXCEPTION: main 
 E/AndroidRuntime( 3635): Process: com.qualcomm.xxx, PID: 3635 
 E/AndroidRuntime( 3635): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/xxxApp.apk”],nativeLibraryDirectories=[/data/app-lib/xxxApp, /system/lib64, /vendor/lib64]]] couldn’t find “libxxxjni.so” 
E/AndroidRuntime( 3635): at java.lang.Runtime.loadLibrary0(Runtime.java:972) 
 E/AndroidRuntime( 3635): at java.lang.System.loadLibrary(System.java:1530) 
… 
09-27 12:17:01.293 E/AndroidRuntime( 3635): at android.os.Handler.dispatchMessage(Handler.java:102) 
09-27 12:17:01.293 E/AndroidRuntime( 3635): at android.os.Looper.loop(Looper.java:154)

这在google的变更说明有 介绍https://developer.android.com/preview/behavior-changes.html#ndk

具体是什么原因呢,怎么解决这种问题呢,google给出了一个官方的解决办法(如上链接),这里也给出另外一种方法。

首先,主要原因是google在N上对.so库的加载进行了限制,限制了so库指从部分指定的路径进行加载,不在这个路径的so提示 
java.lang.UnsatisfiedLinkError: dlopen failed: library “xxx.so” not found 或 
java.lang.UnsatisfiedLinkError: dlopen failed: library “/vendor/lib64/xxx.so” needed or dlopened by “/system/lib64/libnativeloader.so” is not accessible for the namespace “classloader-namespace” 或 其他异常错误提示。

N上对so库加载的搜索路径方式为ld_library_path, runtime path, permit path,不在这个搜索路径下则加载失败。

从代码层面看,主要是类加载器ClassLoader的相关处理, 
code1: (loadedApk.java getClassLoader()) check sdk version 
// DO NOT SHIP: this is a workaround for apps loading native libraries 
// provided by 3rd party apps using absolute path instead of corresponding 
// classloader; see http://b/26954419 for example. 
if (mApplicationInfo.targetSdkVersion <= 23) { 
libraryPermittedPath += File.pathSeparator + “/data/app”; 
}

Code2: (loadedApk.java getClassLoader()) N add a new PermittedPath 
String libraryPermittedPath = mDataDir;

Code3: (native_loader.cpp) use the new namespace rule with search path: ld_library_path, runtime path, permit path.

在明白原因之后, 

先将.so文件push至system/lib
解决办法则是将自己的so加入到允许路径的白名单里面,具体操作为,如果不改代码实现,则导出设备的/vendor/etc/public.libraries.txt 或/etc/public.libraries.txt文件,将so名字添加进去,在push到设备,重启即可。

/public.libraries.txt文件内容如下:

红框是我本人添加的。经测试后可以正常运行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值