您现在的位置是:首页 > 文章详情

Android Studio - 第四十五期 Gradle manifestPlaceholders

日期:2017-07-27点击:397

    最近在学习撸撸的代码规范和写法,有些心得,准备好好写一写~包括了多渠道打版(以前有写过方法),工厂模式,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:

wKioL1l5c6aCAbdJAAEIYRkyE5o544.png

    图2:

wKioL1l5c8jDsbnCAAEFluNEz6s494.png

    这样做的好处在于,如果你的apk版本很多,需要给很多合作厂商提供定制化页面,就可以用上了~

    卧槽,今天喷了好多,希望大家回去自己细化一下,能帮到你~

    wKiom1l5dRTRUWpqAAOaFWzNfo4818.png

    地址:https://github.com/geeklx/MyApplication/tree/master/p027_daojishi_manifestPlaceholders


    

原文链接:https://blog.51cto.com/liangxiao/1951381
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章