Search code examples
androidperformancegradleapk

How to create different version numbers for same apk files with different cpu architecture


In order to reduce Apk size i need to create different apk for each CPU architecture. This is the approach i am using;

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

This creates 2 apk files, the size of both are lower than universalApk. So this fix my apk size problem.

Now the issue is how to upload both of them in Play store.

This stated that the version code of both apk's should be different.

Before adding updated apk to playstore, i open app level build.gradle and update versionCode attribute;

    defaultConfig {
      versionName "1.0.2"
      versionCode 78
    }

So now when i will create multiple apk's, both will have same versionCode. My question is how can i assign different versionCode to both of the generated apk's or do i need to create both apk's one by one after changing their versionCode value.


Solution

  • Yes it is possible

    Here is my gradle file which creates 3 different apk file with different version code. You will find valuable comments in gradle file below.

    apply plugin: 'com.android.application'
    
    android {
    
        splits {
            abi {
                enable true
                reset()
                include 'x86', 'armeabi-v7a', 'armeabi'
                universalApk false
            }
        }
        signingConfigs {
            release {
                keyAlias 'androiddebugkey'
                keyPassword ''
                storeFile file('/Users/anasabubacker/StackOverflow/signing/android_debug.keystore')
                storePassword 'Android'
            }
        }
        compileSdkVersion 26
        buildToolsVersion "27.0.2"
        defaultConfig {
            applicationId "lib4.com.stackoverflow"
            minSdkVersion 17
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            debug {
                debuggable false
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                proguardFile '/Users/anasabubacker/StackOverflow/proguard-android.txt'
            }
        }
    }
    
    // Map for the version code that gives each ABI a value.
    ext.abiCodes = ['armeabi-v7a':1, x86:2, armeabi: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
            }
        }
    }
    
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support:design:26.1.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.1'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    }