1

I am developing an Android application which uses some native code. The native library I am using comes with two variants, one for ARM v6 architecture and one for v7. Therefore in my libs folder I have two folders, 'armeabi' for the v6 lib and 'armeabi-v7a' for the v7 lib. The main problem here is that this lib is around 8mb, so I have 16mb's of libs when only one of these libs is ever required depending on the device - I have 8mb's of bloat which makes my apk rather large.

If I create 2 seperate apk's, with different version codes, one with the v6 lib and one with the v7 lib with different version codes, Google Play does not recognise any difference in device support between these two apk's and tries to replace one with the other.

I have seen this question where this issue is discussed but no solution is offered.

How do I get Google Play to let these two APK's be published along side each other?

Any help would be much appreciated.

Community
  • 1
  • 1
Dean Wild
  • 5,886
  • 3
  • 38
  • 45

4 Answers4

2

This is not (yet) possible. Refer http://developer.android.com/guide/google/play/publishing/multiple-apks.html#SupportedFilters

Supported filters [...]

  • OpenGL texture compression formats [...]
  • Screen size (and, optionally, screen density) [...]
  • API level [...]

Other manifest elements that enable Google Play filters—but are not listed above—are still applied for each APK as usual. However, Google Play does not allow you to publish multiple APKs based on variations of them. Thus, you cannot publish multiple APKs if the above listed filters are the same for each APK (but the APKs differ based on other characteristics in the manifest file). For example, you cannot provide different APKs that differ purely on the characteristics.

Edit: One solution which comes to my mind is plugin based: You deploy one app with core logic, UI, and all that stuff and provide several different "apps" which are signed with the same certificate but only contain the native libs. MXPlayer uses this approach to support different architectures without bloating a singel APK: https://sites.google.com/site/mxvpen/download (see section "Codec").

chrulri
  • 1,822
  • 14
  • 16
  • yes the 'plugin' solution is the approach I am taking, when the app launches it checks the CPU architecture then downloads the required library. Thanks – Dean Wild Jul 13 '12 at 12:51
0

At my case I compiled different libs in same APK and Proguarded it, which helped in reducing the size. But again difference is not substantial but it helped.

Also, I'm not sure about this if it will suit to your needs but if you want to have different APKs necessarily I think different package names will do but again recommendation will be going for a single APK.

That was my little piece of info, for further info and help let me know.

abhy
  • 933
  • 9
  • 13
  • Different package namess would mean two completely separate applications on Google Play which is far from ideal - thanks for the pro guard tip though, I will see what difference it can make – Dean Wild Jul 13 '12 at 12:49
-1

Its possible now, refer to this link.

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

UPDATE :

You need to add the following code in module level build.gradle inside the android tag:

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

This will give you multiple apks to upload for different architecture. According to Android :

Different Android handsets use different CPUs, which in turn support different instruction sets. Each combination of CPU and instruction sets has its own Application Binary Interface, or ABI. The ABI defines, with great precision, how an application's machine code is supposed to interact with the system at runtime.

Also, do remember to push both the apks with different versionCode. A convinient way to that would be to use the following script, provided on the same url later :

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

This goes below the splits code. This gives you multiple apks with your orignal version code multiplied by the architecture code given in abiCodes array in the script above. Eg : if your version code is 5, the mips builds code would be 2005. A universal apk will also be created if you universalApk is true in splits code. The can be a fallover apk in case no architecture build apk is found for a certain device.

legalimpurity
  • 180
  • 3
  • 13