Android架构使用?

48
我有一些本地库,它们相当庞大,会导致应用程序二进制文件的大小增加。我研究了 APK拆分,但维护和QA多个APK不是我想做的事情。
因此,我想在我的发布版本构建风格中使用ndk.abiFilters Gradle属性来排除未使用的架构。(我希望保留调试版本,以便我可以在x86上运行HAXM加速模拟器)。
我考虑只在发布版本中使用armeabi-v7a和arm64-v8a,但我不确定是否值得担心我要删除的其他架构的市场份额。经过大量搜索,我找不到关于ARMv6(armeabi)、MIPS、x86或x86_64市场份额的任何参考资料。我的直觉告诉我后三者几乎不存在,但我对ARMv6不确定。
我在一个论坛上发现了这个链接,其中列出了使用各种架构的手机列表。还有更可靠的东西吗?也许与Android版本仪表板类似的用户百分比?

如果我只为 armeabi-v7a 和 arm64-v8a(或 armeabi、armeabi-v7a 和 arm64-v8a)构建本地库,是否还有其他遗漏的内容?

4个回答

46
首先,如果你担心二进制文件大小的问题,其实并不需要 arm64-v8a,所有这些设备都可以很好地运行 armeabi-v7a 二进制文件。只有当你真正需要将性能最大化时,才可能值得使用它。
至于 armeabi 和 ARMv6,则自 Android 4.4(2013年10月)起,Android 官方不再支持它们;而自 Android 4.0 以来,它应该变得更加少见(从那个版本开始,AOSP 源代码需要进行修改才能继续为 ARMv6 构建)。因此,实际上,如果你不支持低于 4.4 版本的设备,你可以在没有任何显著损失的情况下删除它们。
此外,对于 x86,许多这些设备都配备了相当不错的模拟 arm 二进制文件的功能,因此它们也完全可以使用 armeabi-v7a 版本。
编辑: 上述内容是在 2015 年编写的;现在 Play Store 要求应用程序包括对 arm64-v8a 的支持。但现在的问题更多的是,是否需要完全包含 armeabi-v7a,或者 32 位设备的市场份额是否足够小,可以放弃对其的支持。

4
你是说只有在支持低于4.4的设备或需要v8a的额外性能时,才需要使用armeabi-v8a?而armeabi-v7a已经足够了? - Chase Florell
3
几乎是这样。一些 x86 设备可能不支持 ARM 二进制文件,但我认为大多数设备都支持。还有 MIPS 设备,我认为它们不包括 ARM 模拟。不过这些设备非常罕见(可能比 x86 设备稀少一个数量级,尽管我没有找到任何统计数据来支持这一点)。 - mstorsjo
@mstorsjo,您能否解释一下如何为所有架构使用armeabi-v7a库文件?在我的当前方法中,我必须将库复制到jniLibs / armeabi,jniLibs / armeabi-v7a和jniLibs / x86中,这会使apk变得更大。 - Lahiru Chandima
1
实际上,在Play商店上,没有任何只支持ameabi(而不支持armeabi-v7a)的Android 4.0或更高版本设备。同样地,也没有任何支持mips的设备。因此,即使您的minSdkVersion仅为14,您也可以安全地删除这两个。 - Cristan
4
几乎;自那时以来事情有些变化,但并不多。即使从技术上讲您可能不需要64位支持, 但自2019年8月起,Play Store将要求应用程序提供该版本。 ARMv5 / 6现在已完全弃用(自NDK r16开始弃用,自r17中删除)。 我认为也没有出现过大量新的x86 Android设备 - 英特尔已停止其面向手机/平板电脑的Atom努力。 - mstorsjo
显示剩余2条评论

32
使用应用程序包时,包括其他架构将不再影响二进制文件的大小,因为在这种情况下,Google Play仅向每个设备提供适用于该设备的二进制文件。不仅如此,应用程序更新也会更小更快。
对于仍未使用应用程序包的项目,请参考上述信息。
  • 很遗憾,尽管Android Dashbaord非常有用,但它没有提供架构信息,Google Analytics也是如此。

  • Unity统计数据曾经提供每种架构和CPU功能的统计数据。然而需要注意的是,这些数据并不是普适的统计数据,仅涵盖使用Unity应用程序/游戏的用户。这些信息似乎在公共链接中不再可用,因此我已经用archive.org的最新快照替换了直接链接。


似乎Unity从这些链接中删除了内容。 - Tony
谢谢通知。我会使用archive.org的最新快照更新链接。 - Jose Gómez

22

当我使用Mapbox时遇到了问题,后来发现这个article非常有用。

根据下面的图片,你只需要 armeabi-v7ax86。然后根据Jose Gómez的回答,我只添加了armeabi-v7a,就没有任何问题了。

所以将此行添加到您的app.gradle中。

android {
 defaultConfig {
        //other configs
        ndk {
            abiFilters "armeabi-v7a"
        }
    }
}

如果你还担心使用x86架构的设备(例如ASUS ZenFonelenovo手机)的2%-3%,那么请在app.gradle中使用以下配置。{{}}
ndk {
    abiFilters "armeabi-v7a", "x86"
}

对于Genymotion模拟器,您应该使用x86架构。

enter image description here

更新

如果您在发布apk到play store时遇到此错误:

enter image description here

然后使用{{这个}}。
ndk {
    abiFilters "armeabi-v7a", "arm64-v8a"
}

最后,我建议您使用应用程序包发布APK


4
当我阅读@mstorsjo的答案时,我有点困惑如何真正只使用一个(或两个)本机库,即使它非常简单和直接。因此,我将在此提供一个示例和更多说明(基于我的进一步研究)。
对于每个支持的架构,我们必须在jniLibs文件夹中创建一个特定的文件夹,并在其中放置.so文件。例如,要支持armeabi-v7a(32位)和arm64-v8a(64位):
|--app
|--|--src
|--|--|--main 
|--|--|--|--jniLibs 
|--|--|--|--|--armeabi-v7a 
|--|--|--|--|--|--.so Files 
|--|--|--|--|--arm64-v8a 
|--|--|--|--|--|--.so Files 

使用 armeabi-v7a 您可以支持超过90%的可用设备,但由于其是32位架构,在64位设备上运行会导致性能损失(20-30%){1}。在每种特定情况下,检查受支持设备的实际数量可能非常方便,可以在Google Play控制台中的发布管理>设备目录部分通过指定ABI作为过滤器来完成。
注意:
当您没有为所有架构添加二进制文件时,必须注意以下内容:
如果您的应用程序包含任何其他本地库,则必须确保您也只有相同版本的它们。这是因为Android要求加载的所有本地库都为相同的架构构建。例如,如果加载的第一个本地库是armeabi-v7a,则Android将仅在此之后的所有System.loadLibrary()调用中查找armeabi-v7a库。{1}如果找不到精确的架构,则会抛出java.lang.UnsatisfiedLinkError异常。
我遇到了这个问题,因为我的一些依赖项使用了本地库,其中armeabi-v7a无法再加载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接