Android 架构用法?

Android architecture usage?

我有一些本机库,它们相当大并且使应用程序二进制大小膨胀。我调查了 APK splitting,但我不想维护和 QA 多个 APK。

所以我想使用 ndk.abiFilters Gradle 属性 在我的发布版本风格中排除未使用的架构。 (我想单独留下调试版本,这样我就可以 运行 x86 上的 HAXM 加速模拟器)。

我想在我的发行版本中只包含 armeabi-v7a 和 arm64-v8a,但我不确定是否值得担心我正在放弃的其他架构的市场份额。环顾四周后,我找不到任何关于 ARMv6 (armeabi)、MIPS、x86 或 x86_64 市场份额的参考资料。我的直觉告诉我后三个几乎不存在,但我不确定ARMv6。

我发现 this link on a forum 有一个使用各种架构的电话列表。有什么地方更可靠吗?也许有 % 的用户类似于 Android 版本仪表板?

如果我只是为 armeabi-v7a 和 arm64-v8a(或 armeabi、armeabi-v7a 和 arm64-v8a)构建我的原生库,我可能会错过任何其他东西吗?

首先,如果您担心二进制文件的大小,您实际上并不需要 arm64-v8a,所有这些设备都可以 运行 armeabi-v7a 二进制文件。只有当你真的需要把最后的额外性能塞进去的时候,它才可能是值得的。

至于armeabi和ARMv6; Android 本身不再正式支持它,因为 Android 4.4(2013 年 10 月) - 而且因为 Android 4.0 它应该不太常见(从那个版本开始,AOSP 源需要修改仍然为 ARMv6 构建)。所以在实践中,如果你不支持低于 4.4 的版本,你可以放弃那个版本而不会造成任何重大损失。

此外,对于 x86;这些设备中有许多都附带了令人惊讶的 arm 二进制文件模拟,因此这些设备也可以使用 armeabi-v7a 版本进行管理。

编辑:以上内容写于 2015 年;现在 Play Store 要求应用程序包含对 arm64-v8a 的支持。但是现在下一个问题更多是关于是否需要包含 armeabi-v7a,或者 32 位设备的市场份额是否小到足以放弃支持。

使用 app bundles 时,包含额外的体系结构将不再对二进制大小产生任何影响,因为在这种情况下 Google Play 将仅为每个设备提供适用于该特定设备的二进制文件。不仅如此,应用程序更新也将变得更小、更快。

为仍未使用应用程序包的项目保留之前的信息:

  • 不幸的是,Android Dashboard 尽管很有用,但不提供体系结构信息,Google 分析也不提供。

  • Unity statistics used to provide statistics per architecture and CPU features。但是请注意,这些不是一般统计数据,而是仅涵盖 Unity applications/games 的用户。 public link 中的信息似乎不再可用,因此我已将直接 link 替换为 archive.org.[=13= 中的最新快照]

当我阅读@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 将 ONLY 查找 armeabi-之后所有 System.loadLibrary() 调用的 v7a 库。如果它没有找到确切的体系结构,它将抛出 java.lang.UnsatisfiedLinkError 异常。 {1}

我 运行 遇到这个问题是因为我的一些依赖项使用了本机库,因此 armeabi-v7a 无法再加载。

我在使用 Mapbox, then later found this article 时遇到了这个问题,这非常有用。

根据下图你只需要armeabi-v7ax86。然后根据的回答,我只加了armeabi-v7a,一点问题都没有。

因此将此行添加到您的 app.gradle

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

如果您仍然担心 2% - 3% 使用 x86 架构的用户,例如 ASUS ZenFonelenovo 手机然后在 app.gradle

中使用此配置
ndk {
    abiFilters "armeabi-v7a", "x86"
}

同样对于 genymotion 模拟器,你应该使用 x86 架构

更新

如果您在 Play 商店中发布 apk 时遇到此错误

然后用这个

ndk {
    abiFilters "armeabi-v7a", "arm64-v8a"
}

最后,我建议您使用 app bundle 来发布 APK