UnsatisfiedLinkError X.so is 64-bit instead of 32-bit之Android 64 bit SO加载机制
http://blog.csdn.net/canney_chen/article/details/50633982
今天用户反馈应用闪退崩溃了。然后找呀找…
过程原来是这样的:
还是说下项目背景
- 应用本身是个Android App,感觉这是费话呵,引用了一个JAVA项目。在应用启动后会将App res/raw中的动态库压缩包复制到Sdcard进行解压,然后使用System.load(libPath)加载。libPath是根据System.getProperty(“os.arch”);获取当前处理器的架构动态匹配出来的(例:mnt/sdcard/mylib/armv7l/a.so)。
- 前期开发时只放了armv7l的动态库,当一些有钱的客户买了新的Android设备后,如果处理器是aarch64的架构,问题就来了,加载mnt/sdcard/mylib/aarch64/a.so时,这个路径下是没有so的。
- 与 此同时App项目的lib/目录还是有其它so的。
Canney原创,转载请注明:http://blog.csdn.net/canney_chen/article/details/50633982
为解决上面的这个问题,那当然是再生成一个aarch64的动态库。当这一些就绪后就出了如题UnsatisfiedLinkError a.so is 64-bit instead of 32-bit 的错误。
以下是对产生这个错误进行的相关研究
从错误信息可以看出:
- 从错误信息可以看出当前的a.so为64 bit这个是没有问题的。
- 但从 instead of 32-bit可以看出当前的环境并不是64 bit的而是32 bit。
当前设备是64 bit为什么运行的程序是32 bit环境??
于是找到了下面的这个资料:http://malideveloper.arm.com/downloads/01_Demystifying_64-bit_development_on_Android_Ramin_Zaghi.pdf
这份文档第一部分写了ARM 64-bit Architecture in Android™,其中的一个图拉出来看看。
How Does It All Work?
- All Apps are forked from a background Virtual Machine (VM) process called Zygote
- Multilib devices run two Zygotes (a 32-bit one and a 64-bit one) in parallel!
- When an application is launched on a 64-bit system
- If it contains a supported 64-bit library, it runs as a 64-bit process against the loaded system
- If it contains a supported 32-bit library, it is launched as a 32-bit process
- Applications with no native code are launched using the default virtual machine (typically 64-bit)
上面这段话是原文对上图的说明,能看懂的就略过我下面的解析。
- 所有的app运行都是由Zygote进程创建VM再运行的。
- 支持多种库运行的设备,有两个Zytgote(一个32-bit,一个64-bit)进程同时运行。
- 当App运行在64-bit 系统上时:
- 如果App包含64-bit库,它将运行在一个64位进程中,即VM是由Zytgote 64创建的(图中的2)。
- 如果App包含32-bit 库,它将运行在一个32 bit进程中,即VM是由Zytgote创建的(图中的3)
- 如果App不包含本地库,它将默认运行在64 bit进程中。
对于图中的1,4,5位置表明系统默认运行在64 bit进程中。
有了上面的基础后,对错误就不难理解了:
1. App是否包含本地库、32/64bit是从App/libs目录下进行扫描的。
2. 我的应用在App/libs目录下只有32 bit的so。根据上面的第二条可以判断出我的应用Zytgote(32)创建的VM加载起来的。即32-bit进程在运行。
3. 动态从sdcard加载的a.so(64-bit)对应用启动来说并不知道。
综合上面的分析得出错误产生的原因。
解决办法就是:
- 方法1:所有so都增加aarch64的so(动态加载及App/libs下的so)。
- 方法2:所有so都使用32-bit的(即把原来匹配aarch64目录下的so,删除换成32位的或将aarch64直接匹配到32位的arm7l目录)。
总结一下
- aarch64是armv8架构下的64-bit执行状态, 当然同版本下还有aarch32 32-bit执行状态,具体可以查看[ARMv8 百度百科]
- 64-bit/32-bit 动态库不能混用
- 64-bit处理器可以向下兼容32-bit指令集,即可以运行32-bit动态库
- 当App中没有使用到64-bit处理器特性且动态库容量很大时可以考虑只使用32-bit动态库,这样可以减小安装包的大小。
Canney原创,转载请注明:http://blog.csdn.net/canney_chen/article/details/50633982
UnsatisfiedLinkError X.so is 64-bit instead of 32-bit之Android 64 bit SO加载机制的更多相关文章
- 64位操作系统下IIS报“试图加载格式不正确的程序”错误
缘由:在64位操作系统下IIS发布32位的项目,报“项目依赖的dll无法读取,试图加载格式不正确的程序”错误. 原因:程序集之间的通讯要么全是64位环境下的,要么全是32位环境下的.不能混编访问.不然 ...
- 64位Win7安装+32位Oracle + PL/SQL 解决方法
软件景象:64位win7.32位Oracle 10g. PL/SQL 9.0.4.1644 媒介:以前开辟用的都是32位体系,忽然换到64位上,安装景象真的有点麻烦了,尤其对于PL/SQL只支撑32位 ...
- 计算机组成原理--64位CPU装载32位操作系统,它的寻址能力还是4GB吗?
借由这个问题,今天我们就把 32 位 CPU.64 位 CPU.32 位操作系统.64 位操作系统之间的区别与联系彻底搞清楚.对于这个问题,博主也是一知半解了好长时间啊~ 基本概念 32位的CPU与6 ...
- Android加载SO库UnsatisfiedLinkError错误的原因及解决方案
Android 应用开发者应该对 UnsatisfiedLinkError 这种类型的错误比较熟悉了,这个问题一直困扰着广大的开发者,那么有没有想过有可能你什么都没做错,也会出现这个问题呢? 我们在 ...
- 加载rocksdb实例报错:java.lang.UnsatisfiedLinkError: C:\Users\Administrator\AppData\Local\Temp\librocksdbjni3696928169151614297.dll
项目的缓存中用到了rocksdb,实例化时报错了: Related cause: org.springframework.beans.factory.BeanCreationException: Er ...
- android通过Jni加载so库遇到UnsatisfiedLinkError问题!!!
错误信息: java.lang.UnsatisfiedLinkError: hsl.p2pipcam.nativecaller.NativeCaller at hsl.p2pipcam.manager ...
- 64位主机64位oracle下装32位客户端ODAC(NFPACS版)
64位主机64位oracle下装32位客户端ODAC(NFPACS版) by dd 1.下载Oracle Data Access Components(ODAC) Xcopy的两个版本: x86:(我 ...
- 【电脑常识】如何查看电脑是32位(X86)还是64位(X64),如何知道硬件是否支持64位系统
开始->运行->输入cmd确定->输入systeminfo 回车 待加载完成,就会看到如下信息(不同版本略有差异): 一.如何查看电脑是32位(X86)还是64位(X64) 方法2: ...
- 关于32位windows和64位windows
SysWow64文件夹,是64位Windows,用来存放32位Windows系统文件的地方,而System32文件夹,是用来存放64位程序文件的地方. 当32位程序加载System32文件夹中的dll ...
随机推荐
- ListView中pointToPosition()方法使用具体演示样例
MainActivity例如以下: package cc.testpointtoposition; import java.util.ArrayList; import java.util.HashM ...
- 探讨电子商务新的商业模式O2O
在当前的市场经济大环境下,电子商务成为了众 多中小企业用以开拓市场的主要工具,成为突破企业管理瓶颈的重要手段.必卖电子商务顾问认为,电子商务应该是是线上业务与线下业务的结合.对于从线下渠道 起家的传统 ...
- hdu 1956(混合图的欧拉回路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1956 思路:先将无向边定向,比如1<->3,可以定它的方向为1->3,1的出度++, ...
- go语言获取字符串元素的个数
1:获取字符串字节的个数,并按字节挨个输出 package main import ( "fmt" ) func main() { var str string = "a ...
- python3 - property的使用
传统的绑定属性值,会把属性暴露出去,而且无法检查参数是否合法,如下: class Test(object): def __int__(self,age): self.age = age 为了检查参数 ...
- hadoop集群加入新节点hhbase调试
一.改动vi /etc/hosts 添加节点ip.(没个节点都要加入 ) 二.设置hostname vi /etc/sysconfig/network 把hostname改为nod ...
- ios 制作自已的framework
本文转载至 http://blog.csdn.net/chen505358119/article/details/9190731 ios中我们写的代码有时不愿意让别人看到,可能对它进行封装,生成一 ...
- X明X源面试题《一》
本文转载自zhangkang 今天去明源面试,面试题目如下 1 有两张表 A 学生表 ID Name age 1 李1 ...
- iOS学习笔记(二)——Hello iOS
前面写了iOS开发环境搭建,只简单提了一下安装Xcode,这里再补充一下,点击下载Xcode的dmp文件,稍等片刻会有图一(拖拽Xcode至Applications)的提示,拖拽至Applicatio ...
- java数据结构之枚举
Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素. import java.util.Vector; import java.util.Enumerat ...