【问题标题】:Multiple APK's with different native code具有不同本机代码的多个 APK
【发布时间】:2012-07-13 04:35:56
【问题描述】:

我正在开发一个使用本机代码的 Android 应用程序。我使用的本机库有两种变体,一种用于 ARM v6 架构,一种用于 v7。因此,在我的 libs 文件夹中,我有两个文件夹,'armeabi' 用于 v6 库,'armeabi-v7a' 用于 v7 库。这里的主要问题是这个库大约 8mb,所以当根据设备只需要这些库中的一个时,我有 16mb 的库 - 我有 8mb 的膨胀,这使得我的 apk 相当大。

如果我创建 2 个具有不同版本代码的单独 apk,一个具有 v6 库,一个具有不同版本代码的 v7 库,Google Play 无法识别这两个 apk 之间的设备支持有任何差异,并尝试替换一个和另一个。

我看到this question 在哪里讨论了这个问题,但没有提供解决方案。

如何让 Google Play 让这两个 APK 一起发布?

任何帮助将不胜感激。

【问题讨论】:

标签: android java-native-interface arm apk android-ndk


【解决方案1】:

这(还)不可能。参考http://developer.android.com/guide/google/play/publishing/multiple-apks.html#SupportedFilters

支持的过滤器 [...]

  • OpenGL 纹理压缩格式 [...]
  • 屏幕尺寸(以及,可选的,屏幕密度) [...]
  • API 级别 [...]

其他启用 Google Play 过滤器的清单元素(但未在上面列出)仍照常应用于每个 APK。 但是,Google Play 不允许您发布多个 APK 基于它们的变体。因此,如果上面列出的过滤器对于每个 APK 都相同,则您不能发布多个 APK(但 APK 会因清单文件中的其他特征)。例如,您不能提供仅在特征上有所不同的不同 APK。

编辑:我想到的一种解决方案是基于插件的:您部署一个具有核心逻辑、UI 和所有这些东西的应用程序,并提供几个不同的“应用程序”,这些“应用程序”使用相同的证书进行签名,但仅包含本机库. MXPlayer 使用这种方法来支持不同的架构,而不会膨胀单个 APK:https://sites.google.com/site/mxvpen/download(请参阅“编解码器”部分)。

【讨论】:

  • 是的,“插件”解决方案是我正在采用的方法,当应用程序启动时,它会检查 CPU 架构,然后下载所需的库。谢谢
【解决方案2】:

就我而言,我在同一个 APK 中编译了不同的库并对其进行了 Proguard,这有助于减小大小。但同样的差异并不显着,但它有所帮助。

另外,我不确定它是否适合您的需求,但如果您想拥有不同的 APK,我认为不同的包名称可以,但再次推荐单个 APK。

这是我的一小部分信息,如需更多信息和帮助,请告诉我。

【讨论】:

  • 不同的包名称意味着 Google Play 上有两个完全独立的应用程序,这远非理想 - 不过感谢专业人士的提示,我会看看它能带来什么不同
【解决方案3】:
【解决方案4】:

现在可以了,参考这个链接。

https://developer.android.com/studio/build/configure-apk-splits.html

更新:

您需要在android标签内的模块级build.gradle中添加以下代码:

splits
{

        // Configures multiple APKs based on ABI.
        abi {

          // Enables building multiple APKs per ABI.
          enable true

          // By default all ABIs are included, so use reset() and include to specify that we only
          // want APKs for x86, armeabi-v7a, and mips.

          // Resets the list of ABIs that Gradle should create APKs for to none.
          reset()

          // Specifies a list of ABIs that Gradle should create APKs for.
          include "x86", "armeabi-v7a", "mips"

          // Specifies that we do not want to also generate a universal APK that includes all ABIs.
          universalApk false
        }
}

这将为您提供多个 apk 以针对不同的架构上传。根据安卓:

不同的 Android 手机使用不同的 CPU,这反过来又支持 不同的指令集。 CPU和指令的每种组合 集有自己的应用程序二进制接口,或 ABI。 ABI 非常精确地定义了应用程序的机器代码是怎样的 应该在运行时与系统交互。

另外,请记住使用不同的 versionCode 推送两个 apk。一种方便的方法是使用以下脚本,稍后在同一网址上提供:

// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3]

// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3]

import com.android.build.OutputFile

// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->

  // Assigns a different version code for each output APK
  // other than the universal APK.
  variant.outputs.each { output ->

    // Stores the value of ext.abiCodes that is associated with the ABI for this variant.
    def baseAbiVersionCode =
            // Determines the ABI for this variant and returns the mapped value.
            project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))

    // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
    // the following code does not override the version code for universal APKs.
    // However, because we want universal APKs to have the lowest version code,
    // this outcome is desirable.
    if (baseAbiVersionCode != null) {

      // Assigns the new version code to versionCodeOverride, which changes the version code
      // for only the output APK, not for the variant itself. Skipping this step simply
      // causes Gradle to use the value of variant.versionCode for the APK.
      output.versionCodeOverride =
              baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}

这在拆分代码下方。这为您提供了多个 apk,您的原始版本代码乘以上述脚本中 abiCodes 数组中给出的架构代码。例如:如果您的版本代码为 5,则 mips 构建代码将为 2005。如果您的universalApk 在拆分代码中为真,则还将创建一个通用 apk。如果没有找到适用于某个设备的架构构建 apk,则可以是故障转移 apk。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多