http://blog.csdn.net/canney_chen/article/details/50633982

今天用户反馈应用闪退崩溃了。然后找呀找… 
过程原来是这样的:

还是说下项目背景

  1. 应用本身是个Android App,感觉这是费话呵,引用了一个JAVA项目。在应用启动后会将App res/raw中的动态库压缩包复制到Sdcard进行解压,然后使用System.load(libPath)加载。libPath是根据System.getProperty(“os.arch”);获取当前处理器的架构动态匹配出来的(例:mnt/sdcard/mylib/armv7l/a.so)。
  2. 前期开发时只放了armv7l的动态库,当一些有钱的客户买了新的Android设备后,如果处理器是aarch64的架构,问题就来了,加载mnt/sdcard/mylib/aarch64/a.so时,这个路径下是没有so的。
  3. 与 此同时App项目的lib/目录还是有其它so的。

Canney原创,转载请注明:http://blog.csdn.net/canney_chen/article/details/50633982

为解决上面的这个问题,那当然是再生成一个aarch64的动态库。当这一些就绪后就出了如题UnsatisfiedLinkError a.so is 64-bit instead of 32-bit 的错误。

以下是对产生这个错误进行的相关研究

从错误信息可以看出:

  1. 从错误信息可以看出当前的a.so为64 bit这个是没有问题的。
  2. 但从 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加载机制的更多相关文章

  1. 64位操作系统下IIS报“试图加载格式不正确的程序”错误

    缘由:在64位操作系统下IIS发布32位的项目,报“项目依赖的dll无法读取,试图加载格式不正确的程序”错误. 原因:程序集之间的通讯要么全是64位环境下的,要么全是32位环境下的.不能混编访问.不然 ...

  2. 64位Win7安装+32位Oracle + PL/SQL 解决方法

    软件景象:64位win7.32位Oracle 10g. PL/SQL 9.0.4.1644 媒介:以前开辟用的都是32位体系,忽然换到64位上,安装景象真的有点麻烦了,尤其对于PL/SQL只支撑32位 ...

  3. 计算机组成原理--64位CPU装载32位操作系统,它的寻址能力还是4GB吗?

    借由这个问题,今天我们就把 32 位 CPU.64 位 CPU.32 位操作系统.64 位操作系统之间的区别与联系彻底搞清楚.对于这个问题,博主也是一知半解了好长时间啊~ 基本概念 32位的CPU与6 ...

  4. Android加载SO库UnsatisfiedLinkError错误的原因及解决方案

    Android 应用开发者应该对 UnsatisfiedLinkError 这种类型的错误比较熟悉了,这个问题一直困扰着广大的开发者,那么有没有想过有可能你什么都没做错,也会出现这个问题呢? 我们在 ...

  5. 加载rocksdb实例报错:java.lang.UnsatisfiedLinkError: C:\Users\Administrator\AppData\Local\Temp\librocksdbjni3696928169151614297.dll

    项目的缓存中用到了rocksdb,实例化时报错了: Related cause: org.springframework.beans.factory.BeanCreationException: Er ...

  6. android通过Jni加载so库遇到UnsatisfiedLinkError问题!!!

    错误信息: java.lang.UnsatisfiedLinkError: hsl.p2pipcam.nativecaller.NativeCaller at hsl.p2pipcam.manager ...

  7. 64位主机64位oracle下装32位客户端ODAC(NFPACS版)

    64位主机64位oracle下装32位客户端ODAC(NFPACS版) by dd 1.下载Oracle Data Access Components(ODAC) Xcopy的两个版本: x86:(我 ...

  8. 【电脑常识】如何查看电脑是32位(X86)还是64位(X64),如何知道硬件是否支持64位系统

    开始->运行->输入cmd确定->输入systeminfo 回车 待加载完成,就会看到如下信息(不同版本略有差异): 一.如何查看电脑是32位(X86)还是64位(X64) 方法2: ...

  9. 关于32位windows和64位windows

    SysWow64文件夹,是64位Windows,用来存放32位Windows系统文件的地方,而System32文件夹,是用来存放64位程序文件的地方. 当32位程序加载System32文件夹中的dll ...

随机推荐

  1. Vsphere日记01.ESXi5.5.install

    Vsphere ESXi 5.5 install ESXI 5.5 安装环境需求 1.CPU需求 1.1)Interl CPU 必须支持VT-X技术,且在BIOS中开启.I 系列CPU.exon 系列 ...

  2. Vue实现远程获取路由与页面刷新导致404错误的解决

    一.背景 先简单介绍一下现在项目情况:前后端分离,后端服务是Java写的,前端是Vue+ElementUI. 最近的一个需求是:通过后端Api去获取前端路由表,原因是每个登录角色对应的前端路由表可能是 ...

  3. scrapy初体验 - 安装遇到的坑及第一个范例

    scrapy,python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.scrapy用途广泛,可以用于数据挖掘.监测和自动化测试.scrapy的安装稍 ...

  4. 更新mac系统和更新到Xcode7.3版本出现的: cannot create __weak reference in file using manual reference counting

    之前的编程没有遇到过,应该是苹果官方那边又做了新规吧. 不过不要紧,只要根据这个就能解决报错问题.  Set Build Settings -> Apple LLVM 7.1 - Languag ...

  5. python静态网页爬虫之xpath(简单的博客更新提醒功能)

    直接上代码: #!/usr/bin/env python3 #antuor:Alan #-*- coding: utf-8 -*- import requests from lxml import e ...

  6. 《从零开始学Swift》学习笔记(Day 29)——访问级别

    Swift 2.0学习笔记(Day 29)——访问级别 原创文章,欢迎转载.转载请注明:关东升的博客 访问级别: Swift提供了3种不同访问级别,对应的访问修饰符为:public.internal和 ...

  7. 迷宫问题(java实现)

    1. public class Direction { private int x; private int y; public Direction(int x, int y) { this.x = ...

  8. CAS 源码编译

    准备 :gradle   idea 第一次用Idea 还是有点不熟悉呀,还是eclipse 顺手! 哈哈 下载源码  :我的是4.2.7 解压 导入idea 重点: 调试时候在写 .没时间

  9. 批量索引以提高索引速度 -d --data-binary

    index create update 第1.2行分别为:信息行.数据行,在索引中增加或更换文档delete 移除文档,只包含信息行 Bulk API | Elasticsearch Referenc ...

  10. Exponential Backoff

    f^x(f^y+f-m)+f-n =f^(x+y)+f^(f-m)+(f-n) <?php $exponent=0; w(80,3); function w($input,$base){ glo ...