Android Studio - Phase 45 Gradle manifest Placeholders

Keywords: Android Java Gradle SDK

    Recent learning of code specifications and writing methods, some experience, ready to write ~including multi-channel typing (previously written methods), factory mode, mvp, and recently packaged multi-channel multi-version display different pages of manifest Placeholders configuration method, you should also encounter online and offline environment switching address, changing the head of private key. Big problems, this article is to solve these problems.

    First, configure a node in the Android manifest file. Here, take Aurora as an example:

<meta-data
            android:name="JPUSH_APPKEY"
            android:value="${jush_appkey_value}" />

<meta-data
            android:name="SHOUCANG_CONFIG0"
            android:value="${SHOUCANG_CONFIG_VALUE0}" />

    build.gradle:

buildTypes {
    release {
        //Custom buildconfig field
        buildConfigField("boolean", "APP_ENV", "true")
        //Specify signature as release
        signingConfig signingConfig.release
        //Whether to open confusion
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        //Is zip optimized or not
        zipAlignEnabled true
        //Delete some useless resources
        shrinkResources false
        //
        manifestPlaceholders = [
                "jush_appkey_value": "release key"
        ]

    }
    debug {
        //Custom buildconfig field
        buildConfigField("boolean", "APP_ENV", "true")
        //Specify signature as release
        signingConfig signingConfig.release
        //Whether to open confusion
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        //Is zip optimized or not
        zipAlignEnabled true
        //Delete some useless resources
        shrinkResources false
        //
        manifestPlaceholders = [
                "jush_appkey_value": "debug key"
        ]
    }
}

    There are release node and debug node under bulidtypes node. When formal signature is made, the script will be compiled under release node, and debug node will be used when debugging signature. The main point is the use of manifestPlaceholders. jpush_appkey corresponds to the value of ${jush_appkey_value} previously configured in the Android manifest file.

    log the entry of the program to output the value of the key:

/**
 * log at the program entry to output the value bufen of the key
 */
private void jpush_key_manifest_xml_string() {
    String jpush_appkey;
    try {
        ApplicationInfo appInfo = getPackageManager()
                .getApplicationInfo(getPackageName(),
                        PackageManager.GET_META_DATA);

        jpush_appkey = appInfo.metaData.getString("JPUSH_APPKEY");

        Log.e("jpush_appkey", "jpush_appkey=" + jpush_appkey);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();

    }
}

    Next, I will introduce the configuration switching method of multi-version, multi-page and multi-apk: For example, if you want to type seven versions at once, and all seven versions are different pages, but each module of the page is roughly the same, but the order and size are different, what do you do? Don't tell me to write seven pages and type them separately. And manifestPlaceholders to implement requirements.

    First, build.gradle:

apply plugin: 'com.android.application'
apply plugin: 'android-apt'


def demo = '0000';//DemoAPK
def demo1 = '0001';//DemoAPK1
def demo2 = '0002';//DemoAPK2
def demo3 = '0003';//DemoAPK3
def demo4 = '0004';//DemoAPK4
def demo5 = '0005';//DemoAPK5
def demo6 = '0006';//DemoAPK6


android {

    signingConfigs {
        debug {
            keyAlias '****'
            keyPassword '****'
            storeFile file('Signature file.jks Route')
            storePassword '****'
        }
        release {
            keyAlias '****'
            keyPassword '****'
            storeFile file('Signature file.jks Route')
            storePassword '****'
        }
    }

    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }

    defaultConfig {
        applicationId "com.shining.p010_recycleviewall"
        minSdkVersion 18
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        multiDexEnabled true
        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
        ndk {
            moduleName "native-modbus-jni,libxmediaplayer"
            ldLibs "log", "z", "m", "android", "c"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
        sourceSets.main {
            jni.srcDirs = []
            //LOCAL_LDFLAGS += -fuse-ld=bfd
            //jni.srcDirs 'src/main/jni'
            jniLibs.srcDir 'src/main/libs'

        }
        signingConfig signingConfigs.debug

        manifestPlaceholders = [
                SHOUCANG_CONFIG_VALUE0: ".shoucang.factorys.ShoucangFactory0"
        ]

    }
    buildTypes {
        release {
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug

        }
    }

    def int minSdk = 18;
    def int targetSdk = 23;
    def String appId = 'com.shining.p010_recycleviewall';

    def int vCode = 1;
    def String vNameCode = vCode + "";

    productFlavors {
        //demo
        DemoAPK {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK_" + "T_" + demo
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo1
        DemoAPK1 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK1_" + "T_" + demo1
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo2
        DemoAPK2 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK2_" + "T_" + demo2
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo3
        DemoAPK3 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK3_" + "T_" + demo3
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo4
        DemoAPK4 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK4_" + "T_" + demo4
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo5
        DemoAPK5 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK5_" + "T_" + demo5
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
        //demo6
        DemoAPK6 {
            minSdkVersion minSdk
            applicationId appId
            targetSdkVersion targetSdk
            versionCode vCode
            versionName "DemoAPK6_" + "D_" + demo6
            multiDexEnabled true
            renderscriptTargetApi 19
            renderscriptSupportModeEnabled true
            ndk {
                moduleName "native-modbus-jni,libxmediaplayer"
                ldLibs "log", "z", "m", "android", "c"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir 'src/main/libs'
            }
            signingConfig signingConfigs.debug
        }
    }

    // Custom Output Configuration
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
//                def fileName = "UerbT_v${variant.versionName}_${releaseTime()}_${variant.flavorName}.apk"
                def fileName = "${variant.versionName}.apk"
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }

    productFlavors.all { flavor ->
        def currentMode = flavor.versionName.split("_")[2]
        def currentEnvironment = flavor.versionName.split("_")[1]
        def stValue = true
        // T = CurrtEnvironment Previous Judgment Conditions
        if (currentEnvironment.endsWith("T")) {//Determine whether the beta version ends with T
            stValue = false
        } else {
            stValue = true
        }
        if (currentMode == demo) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo1) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory1", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo2) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory2", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo3) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory3", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo4) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory4", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo5) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory5", STATISTICS_VALUE: stValue]
        } else if (currentMode == demo6) {
            flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory6", STATISTICS_VALUE: stValue]
        }

    }


}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:25.3.0'
    compile 'com.android.support:recyclerview-v7:25.3.0'
    compile 'com.android.support:design:25.3.0'
    compile 'com.android.support:cardview-v7:25.3.0'
    // local jar file
    compile files('libs/alipay-sdk-java20161226110022.jar')
    compile files('libs/alipay-sdk-java20161226110022-source.jar')
    compile files('libs/commons-logging-1.1.1.jar')
    compile files('libs/commons-logging-1.1.1-sources.jar')
    //the third file
    compile 'com.jakewharton:butterknife:8.2.1'
    apt 'com.jakewharton:butterknife-compiler:8.2.1'
    testCompile 'junit:junit:4.12'
    compile 'com.geeklx:library_hios:1.0.4'

    compile project(':glin')
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile 'com.alibaba:fastjson:1.2.17'
    compile 'com.squareup.okio:okio:1.9.0'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.nineoldandroids:library:2.4.0'
    compile files('libs/libammsdk.jar')


}

    Then there are multiple versions of code judgment writing:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        //TODO Multi-Version Switching Write this method bufen
        which_version();
//        ShoucangConfig0.config();//manifestPlaceholders
        super.onCreate(savedInstanceState);
    }
    
    
    private void which_version() {
    if (ConstantNetUtil.VERSION_APK == NetConfig.version_name0) {
        ShoucangConfig.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) {
        ShoucangConfig1.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) {
        ShoucangConfig2.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name3) {
        ShoucangConfig3.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name4) {
        ShoucangConfig4.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name5) {
        ShoucangConfig5.config();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name6) {
        ShoucangConfig6.config();
    }
}

    //TODO multi-version mode bufen
SparseArrayCompat<Class<? extends BaseFragment>> array = which_version_fragment_config();//demo

    private SparseArrayCompat<Class<? extends BaseFragment>> which_version_fragment_config() {
    if (ConstantNetUtil.VERSION_APK == NetConfig.version_name0) {
        return ShoucangConfig.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) {
        return ShoucangConfig1.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) {
        return ShoucangConfig2.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name3) {
        return ShoucangConfig3.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name4) {
        return ShoucangConfig4.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name5) {
        return ShoucangConfig5.getFragments();
    } else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name6) {
        return ShoucangConfig6.getFragments();
    }
    return ShoucangConfig.getFragments();
}

    After running the apk, you will find something magical happening, as follows: (different APK versions of the pages are different, but only one code.)

    Fig. 1:

    Fig. 2:

    The advantage of this is that if you have many versions of apk, you need to provide customized pages to many partners, so you can use ~

    Sleeping trough, sprayed a lot today, I hope you can go back and refine it for yourself, can help you to

    

    Address: https://github.com/geeklx/MyApplication/tree/master/p027_daojishi_manifestPlaceholders


    

Posted by beyzad on Mon, 17 Dec 2018 12:09:05 -0800