Android 64 bit的一些兼容性分析

  1. 云栖社区>
  2. 博客列表>
  3. 正文

Android 64 bit的一些兼容性分析

fashaodexiaohai 2018-07-10 17:16:55 浏览33795 评论0

摘要: Android 64 bit系统的一些兼容性分析 0x0:前言 Android L之后android开始了支持64bit的系统,现在64位的手机越来越多,基本上现在出的新机都是64位的了,所以64位将会是一个趋势,但是对于对于开发者来说,64位android你真的了解么?64位系统是如何无缝兼容32位app的? 0x1:32位兼容分析 *首先在init.

Android 64 bit系统的一些兼容性分析

0x0:前言

Android L之后android开始了支持64bit的系统,现在64位的手机越来越多,基本上现在出的新机都是64位的了,所以64位将会是一个趋势,但是对于对于开发者来说,64位android你真的了解么?64位系统是如何无缝兼容32位app的?

0x1:32位兼容分析

首先在init.zygote32_64.rc里面有这两条开机启动的服务

service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary

这两个进程在系统中就是传说中的zygote进程,所有进程的孵化器,zygote对应app_proccess32,zygote64对应app_proccess64
image1
顾名思义,android所有的应用进程都是fork zygote而来的
image2
image3

  • 那么,当我们启动一个app时,系统是如何选择运行32位模式还是64位模式的,为什么有些app的父进程是zygote,有些是zygote64呢?*

通过看系统源码,从系统启动一个app开始,可以发现系统启动一个应用是通过ActivityManagerService中startProcessLocked方法,主要通过Process中的startViaZygote方法,这个方法最终是向相应的zygote进程发出fork的请求 zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
其中,openZygoteSocketIfNeeded(abi)会根据abi的类型,选择不同的zygote的socket监听端口。
zygote32位监听的端口就是–socket-name=zygote
zygote64就是–socket-name=zygote_secondary
这个abi就是决定该app是fork zygote 还是fork zygote64,这两种模式就决定该app运行在何种环境。
于是,我们继续跟踪abi是从哪里传过来的,发现这个参数在ApplicationInfo的primaryCpuAbi中决定。
而这个值是PackageManagerService在scanPackageLI的时候传进来的。

最终,可以发现这个值是由apk的native 库决定的,可以得出一个判断逻辑:

如果apk中的native库中含有arm64-v8a,则以64位的模式执行,fork zygote64
如果没有,则看有没有armeabi-v7a,armeabi这两个,如果有,则以32位模式执行,fork zygote
如果apk中这三个库都没有,则默认以64位模式执行。

0x2:结论:

**对于android开发者,我们应该要知道些什么呢?
**
1、64位系统本来是为了更快地执行指令,因此,如果我们想提升app在64位机器运行的效率,编译so的时候最好把arm64-v8a编译出来,在Application.mk里面加上APP_ABI = APP_ABI := armeabi armeabi-v7a arm64-v8a,当然,这个会对包size有一定的影响。
2、如果开发者考虑更多的是兼容性的话,特别是引起第三方的sdk的时候,如果sdk没有arm64-v8的库引入来,那么就最好不要把 arm64-v8a编译进去,否则在64位机器会出现一些问题,比如:
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/xxx.so" is 32-bit instead of 64-bit
3、64位和32位运行环境的差异:
动态链接库查找路径:
32位的环境是LD_LIBRARY_PATH=/vendor/lib:/system/lib;
64位的环境是LD_LIBRARY_PATH=/vendor/lib64:/system/lib64;
因此,在编写native层代码的时候,如果有一些代码硬编码了lib里面的so路径的时候,比如硬编码了/system/lib/libc.so 这个路径,在64位运行环境执行就会出错

参考文章:
https://coolpers.github.io/android/64bit/32bit/2015/10/14/android-64bit-32bit-compatibility.html
http://androidxref.com/ 查看系统源码

用云栖社区APP,舒服~

【云栖快讯】诚邀你用自己的技术能力来用心回答每一个问题,通过回答传承技术知识、经验、心得,问答专家期待你加入!  详情请点击

网友评论

fashaodexiaohai
文章3篇 | 关注4
关注
阿里云移动APP解决方案,助力开发者轻松应对移动app中随时可能出现的用户数量的爆发式增长、... 查看详情
移动测试(Mobile Testing)是为广大企业客户和移动开发者提供真机测试服务的云平台... 查看详情
阿里云推出的一款移动App数据统计分析产品,为开发者提供一站式数据化运营服务 查看详情
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效... 查看详情
阿里云总监课正式启航

阿里云总监课正式启航