多个APK使用不同的本机代码

时间:2012-07-13 10:21:40

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

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

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

我已经看到this问题讨论了这个问题但没有提供解决方案。

如何让Google Play让这两个APK相互发布?

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

这还不可能。请参阅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膨胀(参见" Codec")。

答案 1 :(得分:0)

在我的情况下,我在同一个APK中编译了不同的lib并对它进行了Proguarded,这有助于减小大小。但是,差异并不大,但它有所帮助。

此外,我不确定这是否适合您的需求,但如果您想要有不同的APK,我认为不同的包名称会做,但是再次推荐将使用单个APK。

这是我的一小部分信息,有关详细信息和帮助,请告诉我。

答案 2 :(得分:0)

答案 3 :(得分:-1)

现在可以,请参阅此链接。

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
        }
}

这将为您提供多个apks来上传不同的架构。根据Android:

  

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

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

// 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
    }
  }
}

这低于分裂代码。这为您提供了多个apks,您的orignal版本代码乘以上面脚本中abiCodes数组中给出的体系结构代码。例如:如果您的版本代码是5,则mips构建代码将是2005.如果您在分割代码中使用universalApk,则还将创建通用apk。如果没有为某个设备找到架构构建apk,则可以是fallover apk。