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