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-v7a和x86。然后根据的回答,我只加了armeabi-v7a,一点问题都没有。
因此将此行添加到您的 app.gradle
android {
defaultConfig {
//other configs
ndk {
abiFilters "armeabi-v7a"
}
}
}
如果您仍然担心 2% - 3% 使用 x86 架构的用户,例如 ASUS ZenFone 和 lenovo 手机然后在 app.gradle
中使用此配置
ndk {
abiFilters "armeabi-v7a", "x86"
}
同样对于 genymotion 模拟器,你应该使用 x86 架构
更新
如果您在 Play 商店中发布 apk 时遇到此错误
然后用这个
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
最后,我建议您使用 app bundle 来发布 APK
我有一些本机库,它们相当大并且使应用程序二进制大小膨胀。我调查了 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-v7a和x86。然后根据
因此将此行添加到您的 app.gradle
android {
defaultConfig {
//other configs
ndk {
abiFilters "armeabi-v7a"
}
}
}
如果您仍然担心 2% - 3% 使用 x86 架构的用户,例如 ASUS ZenFone 和 lenovo 手机然后在 app.gradle
ndk {
abiFilters "armeabi-v7a", "x86"
}
同样对于 genymotion 模拟器,你应该使用 x86 架构
更新
如果您在 Play 商店中发布 apk 时遇到此错误
然后用这个
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
最后,我建议您使用 app bundle 来发布 APK