最近在学习撸撸的代码规范和写法,有些心得,准备好好写一写~包括了多渠道打版(以前有写过方法),工厂模式,mvp,以及最近刚封装出来的多渠道多版本展示不同页面的manifestPlaceholders的配置方法,大家应该也碰到过线上和线下环境的切换换地址,换私钥的头大问题,本篇就来解决这些问题。

    先在androidmanifest文件配置一个节点,这里以极光为例:

    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';//DemoAPKdef demo1 = '0001';//DemoAPK1def demo2 = '0002';//DemoAPK2def demo3 = '0003';//DemoAPK3def demo4 = '0004';//DemoAPK4def demo5 = '0005';//DemoAPK5def demo6 = '0006';//DemoAPK6android {    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 多版本模式bufenSparseArrayCompat> array = which_version_fragment_config();//demo    private SparseArrayCompat> 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


    

更多相关文章

  1. 安全新手入坑——HTML标签
  2. Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
  3. 手把手带你搭建 Elasticsearch 集群
  4. WPS Office移动版(Android)限时免费,送小米手机
  5. android记忆软件 - iRemember
  6. Android仿游戏答题
  7. 关于Android(安卓)Studio里的Gradle,你所需要知道的都在这里了
  8. Android培训---支持不同的平台版本
  9. 程序中判断Android系统版本

随机推荐

  1. 在SQL Server中实现最短路径搜索的解决方
  2. SqlServer获取存储过程返回值的实例
  3. 关于重新组织和重新生成索引sp_RefreshIn
  4. 通过SQL绘制杨辉三角的实现方法介绍
  5. 基于SQL Server中如何比较两个表的各组数
  6. order by newid() 各种数据库随机查询的
  7. SQL2000 事务回滚问题探讨
  8. 关于PowerDesigner初体验的使用介绍
  9. 基于存储过程的详细介绍
  10. sql动态行转列的两种方法