android 5.0以上so文件关于平台支持问题的浅析

背景
近期,因为一些原因,需要整理一个最简单的插件框架使用的demo,此过程中出现了一个非常诡异的问题,
在实际项目中一直运行正常的一些插件,在demo里面却运行崩溃,得到的异常信息如下:
06-01 15:44:59.462 26609 26609 E InstrumentationHacker: dlopen failed: "/data/data/qihoo.com.pluginloader/files/plugin/safebarcode/work/lib/armeabi/lib/armeabi/libmixed_sample.so" is 32-bit instead of 64-bit
06-01 15:44:59.462 26609 26609 E InstrumentationHacker: java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/qihoo.com.pluginloader/files/plugin/safebarcode/work/lib/armeabi/lib/armeabi/libmixed_sample.so" is 32-bit instead of 64-bit
06-01 15:44:59.462 26609 26609 E InstrumentationHacker: 	at java.lang.Runtime.loadLibrary(Runtime.java:372)
06-01 15:44:59.462 26609 26609 E InstrumentationHacker: 	at java.lang.System.loadLibrary(System.java:1076)
06-01 15:44:59.462 26609 26609 E InstrumentationHacker: 	at com.qihoo360.commoditybarcode.utils.JniInterface.init(JniInterface.java:15)

通过异常信息,可以大致猜到,是由于so平台兼容问题引起的,但是抛出异常的插件里面的so都是32位的存放在lib/armeabi下的,理论上来说,android 64位是可以兼容32位so的,但是为什么会出现这个问题呢?另外,在同样的环境和设备的情况下,实际项目中为什么没有这个问题呢?

android中不同平台so的加载
平时应用开发中,我们的native代码,根据平台/特性的不同需要编译不同版本的so文件,比如:"armeabi", "armeabi-v7a", "arm64-v8a","x86", "mips"等。而android在使用我们的so时,会根据自身cpu的特性,选择最合适的一个版本,如果没有,则选择其次的兼容版本,也就是说,如果同时存在arm64-v8a和armeabi,在64位系统下,系统优先选择aarch64下的so文件,如果aarch64下没有so文件,则依据特性选择兼容的32位版本(armeabi-v7a、armeabi等)。

另外,虽然64位系统能兼容32位指令集,但是64位进程是无法加载32位so的,反过来也一样,因此app要么全使用64位的so,要么全使用32位的so,不能混合使用。所以我们的应用中,针对某一平台,要么不支持,要么所有so都支持,也就是说,在每一个lib下的平台目录中,要么没有so,要么所有so都一致。


我们知道,android所有的进程都是从zygote进程fork()而来,而android 64位系统实际上有两个zygote,分别命名为:zygote、zygote64,一个为32位进程,一个为64位进程,64位的应用通过zygote64位分裂,32位进程通过zygote分裂。

问题分析
综上所述,应用在使用so时,会选择最优方案,如果一个应用中没有任何so文件,在64位系统中以64位进程运行是最优的方案。
而在我们的插件化方案中,宿主程序与插件是分开的,如果宿主程序没有任何so文件,那么64位系统会将其以64位运行。如果插件只支持32位,则插件在加载32位的so文件时,必然出错(不能混用)。
在我们使用System.load()加载一个外部的so时,也有可能存在类似的问题,原因与前述一样。
由于我们在实际项目中,工程中存在armabi的so文件,所以系统将应用以32位进程运行,所以插件能正常运行。

解决方案1
在插件中lib/arm64--v8a下加入一套64位so文件即可,这样它在64位下也能运行。

但是这样会增大插件体积,在某些情况下,我们不会想要带入64位的so。


解决方案2

在宿主的armeabi目录下随便放入一个so文件即可,为了不增大宿主的体积,可以放一个0字节的空文件,按照so命名规范命名。这样64位系统运行应用时,会以兼容32位模式运行。




参考文章:http://blog.csdn.net/canney_chen/article/details/50633982

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值