【问题标题】:How to target different Android architectures?如何针对不同的 Android 架构?
【发布时间】:2015-01-22 23:04:54
【问题描述】:

我目前正在使用不使用 NDK 的 OpenCV (OpenCV4Android) 库(没有 C 或 C++ 代码)。但是,有用于 armeabi、armeabi-v7a、mips 和 x86 的 .so 文件。如果我在项目中包含所有这些,则应用程序大小为 30mb,而如果我只包含 1 个,则应用程序大小仅为 9mb。如果我尝试在不包含该设备架构的 .so 文件的设备上运行该应用程序,它会崩溃,而如果我包含它的 .so 文件,它会工作。

因此,我想将多个 APK 发布到不同的设备架构以减小文件大小。据我所知,这只能在 Application.mk 文件中完成,但我的库没有。还有其他方法可以针对不同的 Android 架构吗?

【问题讨论】:

  • 如果有.so文件,那么它使用的是NDK。
  • 是否可以在安装时(或之后?)指示必须安装单独的 APK?然后你可以将你的应用分成五个,一个核心 APK 和四个特定于架构的应用,在安装核心应用后,它会检测拱门并安装必要的附加 APK。我相信如果他们使用相同的包名,他们可以作为一个单元一起工作,但我从未尝试过这样的事情。对不起,如果我离基地很远。
  • @immibis 我假设 so 文件来自预编译库 ( OpenCV4Android ),在这个应用程序项目中,开发人员没有使用 NDK 来构建 so 文件。

标签: java android android-ndk apk


【解决方案1】:

我目前正在使用不使用 NDK 的 OpenCV (OpenCV4Android) 库(没有 C 或 C++ 代码)。但是,有用于 armeabi、armeabi-v7a、mips 和 x86 的 .so 文件。

正如 immibis 所说,如果有 .so 文件,那么它正在使用 NDK。

如果我尝试在没有包含该设备架构的 .so 文件的设备上运行该应用程序,它会崩溃,而如果我包含它的 .so 文件,它可以工作。

这取决于设备。许多 x86 设备都有libhoudini,它可以运行 ARM NDK 二进制文件,尽管比运行本机 x86 二进制文件要慢。同样,armeabi-v7 设备可以运行armeabi NDK 二进制文件,但速度可能会更慢,尤其是在使用浮点处理的情况下。

因此,我想将多个 APK 发布到不同的设备架构以减小文件大小。据我所知,这只能在 Application.mk 文件中完成,但我的库没有。

Application.mk 文件只控制编译的内容,而不控制分发的内容。

还有其他方法可以针对不同的 Android 架构吗?

使用 Gradle for Android,可能与 Android Studio 结合使用,以及the abi split

android {
  ...
  splits {
    abi {
      enable true
      reset()
      include 'x86', 'armeabi-v7a', 'mips'
      universalApk true
    }
  }
}

splits 闭包中的 abi 闭包:

  • 选择为每个 CPU 架构使用不同的 APK 文件

  • 设置所需架构的白名单

  • 还请求包含所有架构的“通用 APK”,用于不支持按架构划分的单独 APK 的分发渠道

您的构建结果将是按 CPU 架构划分的独立 APK,再加上通用的。

【讨论】:

  • 听到这真是个好消息,所以如果我使用这种方法,我是否能够将多个 APK 部署到商店,让一个应用针对多个架构?
  • ...对每个 APK 使用单个“包含”,例如包含“armeabi-v7a”?
  • @AggieDev:您将在include 语句中列出您想要的架构并跳过您不想要的架构(例如,mips,可能)。每个架构您将获得一个 APK。在 Play Store 上的分发方面,我的理解是它支持每个架构单独的 APK,虽然我没有亲自尝试过。
  • 正如 Kiran 所说,您必须为每种架构使用不同的版本代码,并以“高级模式”将您的 APK 上传到开发者控制台。这是一个可以帮助您从 gradle 正确处理版本代码的要点:gist.github.com/ph0b/69586260bc20c58136ef
【解决方案2】:

应用程序的每个 apk 都应具有由 android:versionCode 指定的唯一版本代码。一些 x86 设备可以运行 ARMv7 二进制文件。因此,为避免 ARMv7 apk 在 x86 设备中下载/使用(以及其他架构的类似情况),您应该订购版本代码。例如,订购版本代码,以便 x86 APK 具有比 ARMv7 更高的版本代码。有关版本控制的更多信息,请访问link

ph0b 在github 共享一个build.gradle 示例,用于为您选择的每个架构创建唯一版本编码的apk。复制如下。

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.abiFilter, 0) * 1000000 + android.defaultConfig.versionCode
        }
    }

建议:Android 多 apk 支持 documentation 建议 如果 apk 大小小于 50mb,则不要使用多个 apk

您通常应该使用多个 APK 来支持不同的设备 仅当您的 APK 太大(大于 50MB)时才配置 到不同设备所需的替代资源 配置。使用单个 APK 支持不同的配置 始终是最佳实践,因为它为应用开辟了道路 对用户来说更新简单明了(也让你的生活更简单 通过避免开发和发布的复杂性)。

【讨论】:

  • 文档将建议大小从 50mb 更新为 100mb。 “只有当你的 APK 太大(大于 100MB)时,你才应该使用多个 APK 来支持不同的设备配置”
  • Could not get unknown property 'abiFilter' for
【解决方案3】:

我不建议使用此模式来构建您的内部版本号。 ARCH - BUILD,因为如果有一天你想回到一个 APK,你将不得不增加你的 versionCode 很多。相反,您可以遵循以下模式: 构建 - 拱形

android.defaultConfig.versionCode * 100 + project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0)

构建 74 的示例构建号将是: 7402 - armeabi-v7a 7408 - x86

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2018-10-17
    • 1970-01-01
    相关资源
    最近更新 更多