组件化开发之Gradle的公共配置抽取与注意事项(优化点)

在组件化开发中,存在不同的组件,为了管理不同组件中的依赖包文件配置,或其他公共参数配置,让项目在日后扩展或维护打下基础,在这些记录Gradle的公共配置及一些注意事项。记录抽取公共的Gradle配置文件,方便日后温习,同时也让大家学习,有问题请多多指教。

正题

  • Gradle文件的运行顺序
  • 抽取公共的Gradle配置文件
  • 公共配置的使用

Gradle的运行顺序

首先你了解gradle文件的运行顺序,不然就有可能获取的变量值为空,从而出现不必要的错误。gradle的执行顺序如下:
setting.gradle -> project build.gradle -> app build.gradle - > 其他model build.gradle

为了让Project目录下的其他build.gradle,都能获取到公共配置的gradle文件内的变量,在运行Project的build.gradle执行前导入所配置的公共的build.gradle文件。

注意:如果抽取了多种不同的Gradle公共配置文件,按照自己的需求导入Gradle文件,导入的位置一定一定要注意执行顺序,不然有可能获取的变量值为空哦!

Gradle的公共配置抽取

在与根目录创建一个文件,把抽取公共的配置写到这个文件中。

//把公用的,可扩展的,加入这个配置文件中
//整个APP项目的配置文件
//ext 自定义增加我们的内容

ext{
    userName = "lu"

    app_android = [
        compileSdkVersion:29,
        buildToolsVersion:"29.0.3",

        minSdkVersion:18,
        targetSdkVersion:29,
        versionCode:1,
        versionName:"1.0",
        testInstrumentationRunner:"androidx.test.runner.AndroidJUnitRunner"
    ]

    //测试依赖
    app_testImpl =[
        "junit": 'junit:junit:4.12',
        "ext_unit": 'androidx.test.ext:junit:1.1.1',
        "espresso_core": 'androidx.test.espresso:espresso-core:3.2.0'
    ]
    //依赖
    app_impl =[
        "constraintlayout":'androidx.constraintlayout:constraintlayout:1.1.3',
        "appcompat": 'androidx.appcompat:appcompat:1.1.0'
    ]

}

app_config配置引入到根目录下的的gradle中

//加载项目的gradle时,就引入app_config配置
apply from:"app_config.gradle"

其他gradle使用app_config中的匹配

//使用方式一 定义一个变量
//rootProject 是gradle内置的
def myName = this.rootProject.userName
println("myName: "+myName)
//糖果语法 相当于js的弱类型,类型可以自动推到
myName = 666
println("myName: "+myName)

//使用方式二
println("使用方式二  myName: ${rootProject.userName}")

注意:

第一种方式:先定义变量后使用(这种方式会优先在本地文件中寻找def定义的变量)

第二种方式,直接使用变量(这种方式会直接到我们的app_config.gradle里面去寻找变量)。每次使用都会在app_config.gradle里遍历寻找变量,这样会耗时更多的时间,建议使用第一种方式,减少耗时时间。(面试可以说,也是一个优化点。)

下面一个app目录下的完成的build.gradle:

apply plugin: 'com.android.application'

//使用方式一 定义一个变量
//rootProject 是gradle内置的
def myName = this.rootProject.userName
println("myName: "+myName)
//糖果语法 相当于js的弱类型,类型可以自动推到
myName = 666
println("myName: "+myName)

//使用方式二
println("使用方式二  myName: ${rootProject.userName}")

//定义变量
def versionInfo = this.rootProject.app_android
def testImpl = this.rootProject.app_testImpl
def appImpl = this.rootProject.app_impl

android {
    compileSdkVersion versionInfo.compileSdkVersion
    buildToolsVersion versionInfo.buildToolsVersion
    defaultConfig {
        applicationId "com.lu.modular_frame"
        minSdkVersion versionInfo.minSdkVersion
        targetSdkVersion versionInfo.targetSdkVersion
        versionCode versionInfo.versionCode
        versionName versionInfo.versionName
        testInstrumentationRunner versionInfo.testInstrumentationRunner
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    //测试的依赖
    testImplementation testImpl.junit
    androidTestImplementation testImpl.ext_unit
    androidTestImplementation testImpl.espresso_core
    //依赖
    appImpl.each{
        k,v-> implementation v
    }

}

注意一个优化点:如果都是 implementation类型的,可以直接一个for循环就可以了,当然配置文件要抽取为同一个集合中即可。

开发时,测试URL与正式URL在gradle中配置

传统写法

public class NetworkUtil {
    public static final String DEBUG_RUL = "http://xxx.xxx.xxx/text";
    public static final String RELEASR_RUL = "http://xxx.xxx.xxx/text";
}

优雅写法

在app_config.gradle中配置url

url =[
    "debug":"http://com.supoin.com/test",
    "release":"http://com.supoin.com/"
]

在app目录的build.gradle中配置

buildTypes {
    debug{
        //配置URL变量
        buildConfigField("String","SERVER_URL","\"${url.debug}\"")
    }
    release {
        //配置URL变量
        buildConfigField("String","SERVER_URL","\"${url.release}\"")
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

使用方式对比:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //手动去判断
        String debugRul = NetworkUtil.DEBUG_RUL;
        String releasrRul = NetworkUtil.RELEASR_RUL;

        //自动根据gradle配置切换
        String url = BuildConfig.SERVER_URL;
    }
}

配置资源路径,方便测试环境,打包不集成到正式环境(节省APK体积大小)

在模块中添加配置资源路径

//配置资源路径,方便测试环境,打包不集成到正式环境
sourceSets {
    main{
        if(!isRelease){
            //如果组件化模式,需要独立运行
            manifest.srcFile 'src/main/debug/AndroidManifest.xml'
        }else{
            //如果集成化模式,整个项目打包进apk中
            manifest.srcFile 'src/main/AndroidManifest.xml'
                java{
                //release时debug目录下的文件(测试的文件)不需要合并到主工程中
                exclude '**/debug/**'
            }
        }
    }
}

注意:1、在mian目录下创建一个debug文件目录,并存放独立运行的AndroidManifest.xml配置文件;2、在包名的目录创建一个debug文件目录存放测试代码(这个debug文件目录名可以自定义,但要与gradle配置文件中一致即可)

总结

  • 配置公共的Gradle导入的时机,可以根据需求而定。
  • 先定义变量后使用。这样可以减少遍历次数,从而减少耗时时间。
  • 注意上面提过的注意事项,减少踏坑,也可以达到优化点。
  • 最好自己动手实践验证。

你可能感兴趣的:(组件化开发之Gradle的公共配置抽取与注意事项(优化点))