目录
1、apk为何要分包(32位安装包、32位64位兼容包和64位安装包)?
2、影响apk适配的cpu架构的因素-原生代码(C/C++代码)
5、Android Studio如何构建支持不同架构的apk
安卓设备的核心是cpu(中央处理器),cpu常用架构有ARM架构和x86架构,cpu又分为32位和64位,因此不同架构也分为32位和64位。
apk为适配市面上不同安卓设备,apk运行在Android系统调用系统驱动时需要兼容不同的CPU架构,apk的应对策略是分包。
大部分手机使用的是ARM架构,ARM架构分为32位架构、兼容32位的64位架构,以及即将推出的只支持64位的架构。
因此apk包分为32位安装包、32位64位兼容包和64位安装包。
注意:32位架构只支持32位安卓应用,兼容32位的64位架构支持32和64位安卓应用,不兼容32位的64位架构只支持64位安卓应用。
为什么原生代码决定apk适配的架构?为什么java代码不影响?
安卓系统的内核是Linux,Linux是使用C语言和汇编语言编写的,Android系统是使用Java语言开发的,Java代码需要通过JNI调用原生代码才能实现对操作系统底层的调度。
而为适配不同的cpu架构,可能需要根据cpu架构的不同编写不同的原生代码。
通常apk中使用原生代码,基本都是将原生代码打包成so库供Java代码使用,因此判断apk支持的cpu架构只需要判断apk中包含的so库的架构即可。
构建apk时会将不同架构的so库分不同的文件夹放置在lib文件夹下,架构和文件夹名称的对应关系如下:
ARM架构:
32 位:lib/armeabi-v7a、lib/armeabi
64 位:lib/arm64-v8a
x86架构:
32 :lib/x86
64 :lib/x86_64
判断apk支持的cpu架构的方法就是检测apk文件的结构即可,具体方法如下:
方法一:查看apk安装包中的lib文件夹下的库文件
使用Android Studio菜单Build->Analyze APK->选择需要检测的apk,查看检测结果lib文件夹下的文件夹,如果有 armeabi、armeabi-v7a 或 x86文件夹,则说明有 32 位库,如有x86_64或arm64-v8a文件夹,则说明有64位库,如两种都有则说明即有32位库也有64位库。
将apk文件后缀改为.zip,然后解压查看lib文件夹下的内容也可以。
方法二:查看安卓引用代码中支持的so库的位数
查看app模块下build.gradle文件下的android标签下的defaultConfig标签下的ndk标签下的abiFilters包含的支持的so库的位数。
abiFilters 的值分别有以下几种,一个安卓应用可以兼容多种,用,分割
ARM架构:
32 位:'armeabi', 'armeabi-v7a'
64 位:'arm64-v8a'
x86架构:
32 位:'x86'
64 位: 'x86_64'
如安卓应用没有使用任何so库,那么该安卓应用不存在主动去调度操作系统的功能,此安卓应用不管运行的手机是32位还是64位都不存在硬件调度的兼容问题,此安卓应用可以称之为32位和64位兼容包。
Android设备如何加载.so文件
arm64-v8a架构:

armeabi-v7a架构:

armeabi架构

x86架构

一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。不同CPU架构的Android手机加载时会在libs下找自己对应的目录,从对应的目录下寻找需要的.so文件;如果没有对应的目录,就会去armeabi下去寻找,如果已经有对应的目录,但是如果没有找到对应的.so文件,也不会去armeabi下去寻找了。
当在项目的build.gradle中设置了abiFilters时,要么对应的Filter的SO文件都有,要么都没有,那么应用程序就会直接向armeabi查找SO文件进行兼容处理。
ndk {
//APP的build.gradle设置支持的SO库架构
abiFilters 'armeabi', 'armeabi-v7a','arm64-v8a'
}

适配不同的平台
目前主流的Android设备是armeabi-v7a架构的,然后就是x86和armeabi了。如果同时包含了 armeabi,armeabi-v7a和x86,所有设备都可以运行,程序在运行的时候去加载不同平台对应的so,这是较为完美的一种解决方案,但是同时也会导致包变大。
armeabi-v7a是可以兼容armeabi的,而v7a的CPU支持硬件浮点运算,目前绝大对数设备已经是armeabi-v7a了,所以为了性能上的更优,就不要为了兼容放到armeabi下了。x86也是可以兼容armeabi平台运行的,另外需要指出的是,打出包的x86的so,总会比armeabi平台的体积更小,对于性能有洁癖的童鞋们,还是建议在打包so的时候支持x86。
第三方平台的.so库怎么处理
第三方的类库只提供了armeabi下的.so文件,我们项目里适配了armeabi-v7a和x86,如果不在对应的文件下放对应的.so文件,就可能导致某些Android设备会出一些问题,我们可以复制armeabi下得.so文件到不同的文件夹下。如果第三方提供了不同平台的.so文件,则复制不同平台的.so文件到项目中对应的文件夹下即可
原因:
目前,Arm架构将逐步限制32位应用的运行。32位应用仅支持跑在小核之上,会导致纯32位应用在性能与功耗等方面出现明显的体验问题。预计2023底上市的旗舰机,Arm的IP架构将只支持64位应用。
政策解读:
Arm将推出只支持64位应用的架构,因此应用要适配64位架构,修改的目的是为了确保应用能够在仅支持 64 位架构的环境中正常运行。
针对政策的解决方案:
确保应用包含64位库即可,如包含不做修改,如未包含,需添加64位库即可。
应用不一定要支持所有 64 位架构,但对于支持的每种原生 32 位架构,应用都必须包含相应的 64 位架构。
修改build.gradle文件下的android标签下的defaultConfig标签下的ndk标签下的abiFilters值然后打包即可。
Android打32/64位兼容包,ABI Filter的使用及其原理 - freewsf - 博客园
如何检测Android应用是32位还是64位_黄毛火烧雪下的博客-CSDN博客_怎么看app是不是64位
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub