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 ...
随机推荐
- nginx源代码分析--nginx模块解析
nginx的模块很之多.能够觉得全部代码都是以模块的形式组织.这包含核心模块和功能模块,针对不同的应用场合.并不是全部的功能模块都要被用到,附录A给出的是默认configure(即简单的httpser ...
- windows 8.1 安装 .Net Framework 3.5
1.挂载IOS虚拟光驱 2.命令提示符(管理员) dism.exe /online /enable-feature /featurename:NetFX3 /Source:F:\sources\s ...
- jfinal 使用类里的方法
package demo; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; imp ...
- 第一百六十六节,jQuery,基础 DOM 和 CSS 操作,元素内容,元素属性,css和class,元素宽度高度、偏移、滚动条
jQuery,基础 DOM 和 CSS 操作,元素内容,元素属性,css和class,元素宽度高度.偏移.滚动条 学习要点: 1.DOM 简介 2.设置元素及内容 3.元素属性操作 4.元素样式操作 ...
- [浪风转载]Jquery取得iframe中元素的几种方法
iframe在复合文档中经常用到,利用jquery操作iframe可以大幅提高效率,这里收集一些基本操作 DOM方法:父窗口操作IFRAME:window.frames["iframeSon ...
- Servlet 调试
测试/调试 Servlet 始终是开发使用过程中的难点.Servlet 往往涉及大量的客户端/服务器交互,可能会出现错误但又难以重现. 这里有一些提示和建议,可以帮助您调试. System.out.p ...
- Tomcat虚拟目录
x先来看一段server.xml文件里的配置: <Host appBase="" autoDeploy="true" debug="0" ...
- 利用Lucene将被索引文件目录中的所有文件建立索引
1.新建两个文件夹htm和index,其中htm中存放被索引的文件,index文件中存放建立的索引文件. 2.新建解析目录中所有文件的类,用来解析指定目录下的所有文件. import java.io. ...
- java随手记
javaagent可以hook字节码处理 java -javaagent:jebloader.jar -jar xxx.jar 结合javassist,可以动态替换方法内容 import java.i ...
- Django项目部署(django+guncorn+virtualenv+nginx)
一.说明 为了django项目部署到生产环境上,能够稳定的运行,且能够同时指出http和https的访问,对django的部署进行了一些研究,决定采用django + gunicorn + virtu ...