带so库的apk正确内置到system/app详解

序:目前有个项目,以前不带so的时候可以内置嵌入到/system/app下面,现在接入so就遇到一启动就奔溃的问题,下面我来详细说说怎么解开这个问题的吧。


先说原因


产生的日志(apk的包名为com.dangbeiaddemo)

java.lang.UnsatisfiedLinkError: Couldn't load dbasdpi from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dangbeiaddemo-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.dangbeiaddemo-1, /vendor/lib, /system/lib]]]: findLibrary returned null

根据日志的反馈,我去查看了下System.loadLibrary的源码看到一行

带so库的apk正确内置到system/app详解_第1张图片

所以肉戏来了,关键点就在loader.findLibrary()

看了半天源码和资料,ClassLoader的那个findLibrary()实际上会在两个部分的文件夹中去寻找System.loadLibrary()要load的那个library,一个部分是,构造ClassLoader时,传进来的那个library path,另外一个部分是system property。在android系统中,查找要load的library,实际上会在nativeLibraryDirectories=[/data/app-lib/com.dangbeiaddemo-1, /vendor/lib, /system/lib]中查询。

我们通过log查看可以知道:loader为PathClassLoader,find的文件夹路径为[DexPathList[[zip file "/data/app/com.dangbeiaddemo-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.dangbeiaddemo-1, /vendor/lib, /system/lib]]]

注意:不同的手机不同的版本可能路基稍微有点不一样

所以就是一开始通过root 权限将apk直接push到/system/app目录下,导致启动无法加载so文件奔溃


解决方案


所以分多步入手:

1.尽量能加载出来so,下面这个方法在某些机型可用

System.load(context.getDir("lib", 0).getParentFile().getAbsolutePath());

2.不能加载出来,我给它拷贝进去

当你push 一个apk到/system/app文件夹下面的时候,你可以push so文件到/system/lib文件下面,这样就可以正常运行了。

3.需要捕获异常才能进行二次调用。

正常情况下,第一次调用就会抛出UnsatisfiedLinkError,你需要try catch这个异常。一开始我是用Exception去捕获的,所以直接奔溃,下图为异常结构图:


带so库的apk正确内置到system/app详解_第2张图片

4.实在无法加载的,必须要在代码里做处理,不调用native方法


参考链接:

ava中System.loadLibrary() 的执行过程

你可能感兴趣的:(带so库的apk正确内置到system/app详解)