作者君主要做SDK开发,对接一些厂商或运行商的普通应用或系统应用。
当对接系统应用时,由于系统应用是由于覆盖机型比较广,会碰到Android多个版本机型,有的可能出现so找不到的问题。
普通应用
普通install安装apk的方式,apk会被安装在 /data/app 目录下,那么So则会被映射到/data/app/项目目录下/lib。
系统应用
1.apk采用预装的方式:
首次安装只能通过直接push到/system/app/下的方式来安装,而不是如普通应用般采取install的方式。
2.系统应用升级:
android在开机扫描应用的时候会对 相应目录进行扫描,如果发现 data/app目录下 存在和系统应用同包名的应用,并且版本号比系统应用的版本号更高则构成升级关系,校验签名等安全验证通过。此时data/app下的这个应用就是系统应用
3.so加载
而push到系统目录下如system/app/....,则会优先寻找system/lib(lib64)目录下的so,由于so
不会自动释放到该目录下,所以需要手动push到该路径下。
4.Android版本适配的问题:
- 4.4(含)及以下系统:push到Android系统的/system/lib目录
- 5.0(含)及以上系统:push到Android 系统的 /system/app/应用部署文件夹/lib/系统架构/目录中进行集成;不推荐这两个so文件拷贝到/system/lib或者/system/lib64目录中,已知在Android N上。
PackageManager扫描so版本出错
1.背景
作者君还遇到过这样的问题,有时候为了减少包的大小或者其他,不会把所有ABI类型的so都放进目录,另外so的提供者团队没有提供64的so(哈哈,如果提供了,下面的问题直接就没有了,那为什么还拿出来说呢,主要是简单地了解一下系统底层的一些基本原理,感兴趣的可以看下一下~~)
2.问题:
机型类型是64位的,其他apk仅提供了64位的so。而某个apk由于只集成了32位so, install安装是正常的,但是把apk通过push到/system/app下,so放到/system/lib下则报如下错误:
abcdefg-xxx.so is 32-bit instead of 64-bit
32位机器上当然是正常的。
一般情况下,64位的操作系统可以兼容32位的库文件,所以仅含有32位的
apk正常情况下也可以在64的机器上跑起来。
3.原因:
那么为什么会出错呢?首先是系统级应用,需要理解Android系统的原理(当然啦,也许厂商定制了一番,那则另一回事。):
系统有几个属性,其中app.info.primaryCpuAbi这个值用来决定apk关联ABI类型。而PackageManager会对这个值有所影响。比如:通过apk包里包含的so库的架构来决定app的primaryCpuAbi的值。
1.系统apk或者普通的apk, 如果统的 /system/app/应用部署文件夹/lib/系统架构/目录下so文件存在,则以此so文件来确定primaryCpuAbi的值
2.如果是系统apk, 包里又不存在.so文件,就会进一步根据/system/app/项目包名/lib和/system/app/项目包名/lib64是否存在,来确定它的primaryCpuAbi值
另外:
如果机器里有64位的apk,且PackageManager扫描到第一正好是这个apk,PackageManager调整所有apk要加载的都是64位的so。不再去加载32位的so,那么只含32位so的apk就会跑出异常。反之,则64位的apk正常运行,32位的则出错。
尾语
作者君能力有限,如有错处,请书友们指导,作者君会第一时间修改。
一起学习一起进步ღ( ´・ᴗ・` )比心