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 ...
随机推荐
- javascript 最佳实践 ( 24 章 )
代码约定 易于维护, 形成了一套 JavaScript 代码书写的约定: 跟别的语言差不多, 不过 javascript 中的大括号一定要放在 行尾, 例如: function abc() { // ...
- 使用神器MobaXterm连接远程mysql和redis
https://mobaxterm.mobatek.net/download-home-edition.html mysql redis 连接测试 mysql 127.0.0.1 3307 密码使用线 ...
- PowerDesigner 建模后如何导入到数据库
from:https://jingyan.baidu.com/article/7f766daf465e9c4101e1d0d5.html 大家都知道PowerDesigner是一个数据库建模工具,但是 ...
- centos6.4下安装mysql5.7.18
1.安装前工作 在安装前需要确定现在这个系统有没有 mysql,如果有那么必须卸载(在 centos7 自带的是 mariaDb 数据库,所以第一步是卸载数据库). 卸载系统自带的Mariadb: 查 ...
- boost::lockfree::stack
#include <boost/thread/thread.hpp> #include <boost/lockfree/stack.hpp> #include <iost ...
- [Spring MVC]学习笔记--DispatcherServlet
在上一篇我们介绍了Servlet,这一篇主要来看一下MVC中用到的DispatcherServlet(继承自HttpServlet). 1. DispatcherServlet在web.xml中被声明 ...
- E - I Hate It(基础线段树)
E - I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descr ...
- Java工程师面试题整理[社招篇]
http://blog.csdn.net/jackfrued/article/details/44921941 1.面向对象的特征有哪些方面?2.访问修饰符public,private,protect ...
- eclipse远程debug Java程序
使用Eclipse JPDA远程调试Java程序 本文将介绍使用Eclipse JPDA,在Eclipse的开发环境下对远程运行的Java程序进行调试操作. 请按以下步骤进行(本人已经在Eclipse ...
- py 与 pyc 文件
本文要说明的问题 pyc 文件是什么 pyc 文件的作用 py 与 pyc 文件冲突 pyc 文件是什么 当 py 文件加载后,py 文件被二进制编码成 pyc 文件.py 文件的修改时间被记录到 p ...