最近在学习撸撸的代码规范和写法,有些心得,准备好好写一写~包括了多渠道打版(以前有写过方法),工厂模式,mvp,以及最近刚封装出来的多渠道多版本展示不同页面的manifestPlaceholders的配置方法,大家应该也碰到过线上和线下环境的切换换地址,换私钥的头大问题,本篇就来解决这些问题。
先在androidmanifest文件配置一个节点,这里以极光为例:
- <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 {
- //自定义buildconfig字段
- buildConfigField("boolean", "APP_ENV", "true")
- //指定签名为release
- signingConfig signingConfig.release
- //是否开启混淆
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- //是否zip优化
- zipAlignEnabled true
- //删除一些无用资源
- shrinkResources false
- //
- manifestPlaceholders = [
- "jush_appkey_value": "release key"
- ]
-
- }
- debug {
- //自定义buildconfig字段
- buildConfigField("boolean", "APP_ENV", "true")
- //指定签名为release
- signingConfig signingConfig.release
- //是否开启混淆
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- //是否zip优化
- zipAlignEnabled true
- //删除一些无用资源
- shrinkResources false
- //
- manifestPlaceholders = [
- "jush_appkey_value": "debug key"
- ]
- }
- }
在bulidtypes节点下有release节点和debug节点,正式签名时就会走release节点的下编译脚本,调试签名时就会走debug节点。主要点就是manifestPlaceholders的用法,jpush_appkey对应的就是之前在androidmanifest文件配置的${jush_appkey_value}的这个值。
在程序入口出打上log,用来输出key的值:
- /**
- * 在程序入口出打上log,用来输出key的值bufen
- */
- 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();
-
- }
- }
接下来给大家介绍多版本多页面多apk的配置切换方法:举个例子:如果你要一次性打七个版本,而且七个版本都是不同的页面,但是页面各个模块大体一样,只是顺序和大小不同,你要怎么做,别告诉我写七个页面分别打版哈~太low了~you know~这里就利用多版本打版和manifestPlaceholders来实现需求。
首先是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('签名文件.jks路径')
- storePassword '****'
- }
- release {
- keyAlias '****'
- keyPassword '****'
- storeFile file('签名文件.jks路径')
- 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
- }
- }
-
- // 自定义输出配置
- 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 == currentEnvironment 以前的判断条件
- if (currentEnvironment.endsWith("T")) {//判断是否为测试版 是否以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')
-
-
- }
接着就是多版本的代码判断书写:
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- //TODO 多版本切换 写此方法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 多版本模式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();
- }
这样跑完apk你会发现会有神奇的事情发生,如下图:(不同的apk版本出来的页面也是不同的,但是只用了一份代码。)
图1:
图2:
这样做的好处在于,如果你的apk版本很多,需要给很多合作厂商提供定制化页面,就可以用上了~
卧槽,今天喷了好多,希望大家回去自己细化一下,能帮到你~
地址:https://github.com/geeklx/MyApplication/tree/master/p027_daojishi_manifestPlaceholders