带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的源码看到一行
文章图片
所以肉戏来了,关键点就在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去捕获的,所以直接奔溃,下图为异常结构图:
文章图片
4.实在无法加载的,必须要在代码里做处理,不调用native方法
参考链接:
【带so库的apk正确内置到system/app详解】ava中System.loadLibrary() 的执行过程
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 精神,带我走向人生的天堂!
- 带有Hilt的Android上的依赖注入
- python自定义封装带颜色的logging模块
- 皮夹克
- 油菜花田的小路像绶带
- 不废话,代码实践带你掌握|不废话,代码实践带你掌握 强缓存、协商缓存!
- 《离开却带走了“能量的魔杖”(52)》能量爱情公寓
- 《生不带来死不带去》
- 爸爸带我买文具。