`
喧嚣求静
  • 浏览: 585334 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

转载-Android系统支持的CPU架构

 
阅读更多

原文链接

早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种!

Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。

应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。

为什么你需要重点关注.so文件

如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文 件了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经 嵌入了.so文件,并依赖于不同的ABI。

例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable,SQLCipher等,你都已经在生成的APK文件中包含.so文件了,而你需要关注.so文件。

Android应用支持的ABI取决于APK中位于lib/ABI目录中的.so文件,其中ABI可能是上面说过的七种ABI中的一种。

 

Native Libs Monitor 这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数库或者框架。

当然,我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些。

很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特 定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新, 例如硬件fpu,更多的寄存器,更好的向量化等)。

我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为 Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,如果在对应的lib/ABI目录中存在.so文件的 话。

App中可能出错的地方

处理.so文件时有一条简单却并不知名的重要法则。

你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。

当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的 话,会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支 持armeabi-v7a和armeabi)。

其他地方也可能出错

当你引入一个.so文件时,不止影响到CPU架构。我从其他开发者那里可以看到一系列常见的错误,其中最多的是"UnsatisfiedLinkError","dlopen: failed"以及其他类型的crash或者低下的性能:

使用android-21平台版本编译的.so文件运行在android-15的设备上

使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。

这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。

混合使用不同C++运行时编译的.so文件

.so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。 作为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的 C++运行时。

这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。

没有为每个支持的CPU架构提供对应的.so文件

这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。

例如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库:

compilepl.droidsonroids.gif:android-gif-drawable:1.1.+’

发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy S6,最终可以发现只有64位目录下的.so文件被安装进手机。

解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置

ndk.abiFilters

显示指定支持的ABIs。

最后一点: 如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。

将.so文件放在错误的地方

我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:

  • Android Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定)
  • Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)
  • AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)
  • 最终APK文件中的lib/ABI目录中
  • 通过PackageManager安装后,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。

只提供armeabi架构的.so文件而忽略其他ABIs的

所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,因此似乎移除其他ABIs的.so文件是一个减少APK大小的好技巧。但事实上并不是:这不只影响到函数库的性能和兼容性。

x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性 能(ART,webview,media等等)。

以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版

 本的APK可以在build.gradle中如下配置:

android {
   ... 
   splits {
     abi {
       enable true
       reset()
       include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
       universalApk true //generate an additional APK that contains all the ABIs
     }
   }
   // map for the version code
   project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
   android.applicationVariants.all { variant ->
     // assign different version code for each output
     variant.outputs.each { output ->
       output.versionCodeOverride =
           project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode
     }
   }
}

 

 

分享到:
评论

相关推荐

    arm-linux-androideabi-4.9.zip

    《深入理解ARM-LINUX-ANDROIDEABI-4.9:构建NDK编译环境与CPU架构库》 在移动设备开发领域,Android NDK(Native Development Kit)扮演着至关重要的角色,它允许开发者使用C/C++编写底层代码,以实现高性能计算或...

    aarch64-linux-android-gdb.zip

    aarch64-linux-android-gdb是专为aarch64架构的Android系统定制的GDB版本。它包含了对aarch64指令集的支持,能够与运行在该架构上的Android应用进行交互。开发者可以利用它来调试本地C/C++代码,这对于处理性能关键...

    aarch64-linux-android-4.9

    标题中的"aarch64-linux-android-4.9"是一个针对Android平台的交叉编译工具链的标识符,它主要用于在非Android系统(如x86架构的Linux或Windows)上构建适用于Android设备的ARM64架构(aarch64)的应用程序和库。...

    aarch64-linux-android-4.9(windows-64位)

    标题 "aarch64-linux-android-4.9(windows-64位)" 指的是一个特定版本的Android NDK工具链,适用于64位Windows操作系统,用于编译针对AArch64架构(也称为ARM64)的Linux Android应用程序。NDK(Native ...

    mips64el-linux-android-4.9

    标题"MIPS64el-linux-android-4.9"所代表的是一个特定的交叉编译工具链,用于构建针对MIPS64el(Little Endian)架构的Linux应用程序,且这个工具链是为Android平台设计的。这里的“4.9”指的是GCC(GNU Compiler ...

    mips64el-linux-android-4.9.rar

    在文件名称列表中只有一个条目:“mips64el-linux-android-4.9”,这可能是一个包含编译器、链接器和其他工具的工具链,这些工具用于构建和运行MIPS64EL架构上的Android应用。如果开发者需要在新环境下支持这种架构...

    ksoap2-android-assembly-2.6.5-jar-with-dependencies.jar

    ksoap2-android-assembly-2.6.5-jar-with-dependencies.jar 要是需要最新的,下载地址: http://code.google.com/p/ksoap2-android/

    mipsel-linux-android-4.9.rar

    总结起来,"mipsel-linux-android-4.9.rar"是一个关键的开发资源,为MIPS和MIPS64架构的Android设备提供了必要的交叉编译工具,使得开发者能够在非MIPS系统上创建高效且兼容的原生代码。对于需要在MIPS设备上运行的...

    android手机cpu架构查询快捷路径

    在Android开发过程中,了解手机的CPU架构是至关重要的,因为它直接影响到应用的性能优化和兼容性。本篇文章将详细介绍如何快捷地查询Android手机的CPU架构信息。 首先,我们可以从手机型号入手来初步判断CPU的型号...

    opencv-3.2.0-android-sdk下载

    标题"opencv-3.2.0-android-sdk下载"表明这是一个针对Android平台的OpenCV版本,具体为3.2.0版的SDK。SDK(Software Development Kit)是一套用于开发软件的工具集合,通常包括库文件、头文件、示例代码、文档以及...

    mips64el-linux-android

    2. 解压下载的压缩包,找到文件 "misps64"(根据提供的文件名列表,可能有误,正确名称应为 "mips64el-linux-android*",如 "mips64el-linux-android-ld" 或 "mips64el-linux-android-gcc" 等)。 3. 将解压得到的...

    ffmpeg包含android三个cpu架构so.zip

    使用ndk-r21e、ffmpeg-4.2.5编译的三个架构的so库和头文件,亲测可用; 相关的博客链接:https://blog.csdn.net/qq_32506429/article/details/122144239

    spatialite-android所需jar包

    `armeabi.jar`和`spatialite-android-library.jar`分别对应于armeabi架构的Java库和Spatialite的Android库。`spatialite-android-library.jar`包含了与Spatialite交互所需的Java API,使得开发者可以通过Java代码...

    faac-android包含3个cpu的so和头文件.zip

    Android平台支持多种架构的CPU,如armeabi、armeabi-v7a、arm64-v8a、x86和x86_64等。在"faac-android"的压缩包中,包含了针对不同CPU架构的FAAC SO库。这些预编译的库确保了FAAC能在各种Android设备上运行,无论其...

    OpenCV-2.4.2-android-sdk.zip

    标题"OpenCV-2.4.2-android-sdk.zip"指的是OpenCV库的特定版本——2.4.2,专为Android平台设计的软件开发工具包(SDK)。这个SDK包含了开发者在Android设备上使用OpenCV所需的所有资源,如库文件、示例代码、文档...

    高通平台android-modem 架构总结

    本文将基于“高通平台android-modem 架构总结”这一主题,深入探讨高通Android Modem架构的关键组件和工作原理。 首先,我们要理解的是高通Modem的硬件架构。高通的Modem通常集成在骁龙(Snapdragon)系列SoC...

Global site tag (gtag.js) - Google Analytics