简析强大的Android Studio实现一键切换多个代码环境

在安卓项目中,经常会碰到这样的需求,我们需要在同一台手机上装上同一个App,App内部逻辑一摸一样,但可能对接的后端的接口以及数据库不一致,从而产生多个代码环境,比如测试化境,开发环境,生产环境等等。对于此种需求,我们要面临的问题有以下几个:

1.我们如何写一个配置文件,然后再按需求注释掉不需要的代码,而留下需要的代码。

2.我们如何将配置文件的某些配置被AndroidManifest文件引用,以便在切换环境后产生不同配置

3.我们如何将配置文件的某些配置被代码应用,以便在切换环境后产生不同数据

针对以上问题,我查询了一些资料,在此做个小总结,同时也写了一个非常简易的demo,希望为万能的网友们提供些许参考。

    1.写配置文件:我们可以在项目的根目录创建一个“config.gradle”文件,内部写上你需要切换的配置,如下

ext {
    android = [
            compileSdkVersion: 28,
            buildToolsVersion: "28.0.3",
            minSdkVersion    : 19,
            targetSdkVersion : 26,
            versionCode      : 1,
            versionName      : "1.0.0",

            //Pro环境
//            appLabel         : "一键切换PRO",
//            applicationId    : "com.test.demo.quicklychange.pro",
//            envName          : "Pro",
//            envNumber        : "310"

            //Test环境
//            appLabel         : "一键切换Test",
//            applicationId    : "com.test.demo.quicklychange.test",
//            envName          : "Test",
//            envNumber        : "320"

            //UAT环境
            appLabel         : "一键切换UAT",
            applicationId    : "com.test.demo.quicklychange.uat",
            envName          : "UAT",
            envNumber        : "330"
    ]

    dependencies = [
            "appcompat-v7" : "com.android.support:appcompat-v7:28.0.0",
            "junit"        : "junit:junit:4.12",
            "runner"       : "com.android.support.test:runner:1.0.2",
            "espresso-core": "com.android.support.test.espresso:espresso-core:3.0.2"
    ]
}

2.让工程根目类的build.gradle引用此配置文件,如下,引用成功后就可以实现条条道路通罗马了

apply from: "config.gradle"

buildscript {

    repositories {
        google()
        jcenter()
    }

3.在app的build.gradle中引用rootProject的配置参数,同时开放出口:

    1)给AndroidManifest文件引用

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    defaultConfig {
        applicationId rootProject.ext.android.applicationId
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        /**
         * 此处配置数据用于AndroidManifest文件调用
         */
        manifestPlaceholders = [
                APP_LABEL: rootProject.ext.android.appLabel,
                PAK_NAME : rootProject.ext.android.applicationId
        ]
    }

    2)给代码引用

buildTypes {
        /**
         * 此处配置数据用于代码中调用
         */
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "int", "envNumber", rootProject.ext.android.envNumber
            buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "int", "envNumber", rootProject.ext.android.envNumber
            buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""
        }
    }

4.在AndroidManifest文件中使用被引用的配置,我们将通过meta-data的方式实现

     1)改变app的名称

    

        
        

    2)改变Provider


        

        

            
        

5.在代码中使用被引用的配置,我们将通过调用BuildConfig这个java类实现

 private void initData() {
        //此处数据实际来源于配置文件
        mTvMainEnvName.setText("这是" + BuildConfig.envName + "环境");
        mTvMainEnvNumber.setText("环境代号" + BuildConfig.envNumber);
    }

以上,是我总结的几个关键流程点,碰到的问题有:

1)我定义的“envNumber”的配置参数在配置文件中是一个String,而在代码中使用时是一个int

2)我定义的“envName”的配置参数在配置文件中是一个String,在代码中也是一个String,需要在引用的时候头尾加上 "\"",像这样:

 buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""

最后,将demo的地址公布一下,详细的过程可查阅demo

https://github.com/blood1093/QuicklyChange

你可能感兴趣的:(问题记录)