Android Gradle的神奇之处 ---- 组件化优化

build优化

  • 1 组件化优化
    • 1.1 library和application
    • 1.2 组件化配置优化

1 组件化优化

首先先创建一个组件化的工程,包括业务层、基础层
Android Gradle的神奇之处 ---- 组件化优化_第1张图片
其实在创建组件的时候,没有必须要说直接创建一个Library,可以直接创建application,然后通过gradle做build配置即可
Android Gradle的神奇之处 ---- 组件化优化_第2张图片
在创建base组件库的时候,可以直接创建一个Library
Android Gradle的神奇之处 ---- 组件化优化_第3张图片
Android Gradle的神奇之处 ---- 组件化优化_第4张图片
在setting.gradle中可以看到这些组件已经注册进来了

include ':app'
include ':business:main'
include ':core:common'
include ':base:baseLib'

1.1 library和application

app壳工程依赖business/main模块,因为business/main是一个application是一个可以单独运行的模块,只有library才可以被依赖,因此当组件化打包的时候,business/main是作为一个library进来的

plugins {
    //id 'com.android.application'
    id 'com.android.library'
    id 'kotlin-android'
}

android {
    compileSdk 31

    defaultConfig {
    	//不能有appId的存在
        //applicationId "com.study.main"
        minSdk 21
        targetSdk 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

每个业务模块之前其实是解耦的,如果在测试的时候,只需要测试某个模块,那么可以单独打成一个apk提供给测试,跑整体流程的时候,又可以作为library打进app壳,下面就介绍一下简单的方式来配置组件化

step1:创建config.gradle

ext {
    //模块单独运行 设置为true
    //打包运行 设置为false
    isModuleDebug = true
}

step2:business/main依赖这个脚本插件

# business/main/build.gradle
//config.gradle不是跟 business/main/build.gradle在同级目录下,需要声明路径
apply from:"${rootProject.rootDir}/config.gradle"

if(isModuleDebug){
    apply plugin:'com.android.application'
}else{
    apply plugin:'com.android.library'
}
apply plugin:'kotlin-android'

如果是打包的模式,那么就是以library的形式存在,如果是测试模式,那么就可以单独打包application

与library和application对应的就是applicationId

defaultConfig {
   if(isModuleDebug){
       applicationId "com.study.main"
   }
   ......

step3:清单文件的配置

sourceSets {
   main{
       if(isModuleDebug){
           manifest.srcFile 'src/main/debug/AndroidManifest.xml'
       }else {
           manifest.srcFile 'AndroidManifest.xml'
       }
   }
}

在测试环境下,可能有一些测试专用的activity,可以放置在debug下的清单文件中,正式环境下的就是用src/main文件夹下的清单文件

step4:调试模式场景下,不用将组件依赖到app壳

if(!isModuleDebug){
    implementation project(':business:main')
}

1.2 组件化配置优化

前面讲到的,是针对单独的一个模块进行组件化配置,如果你的项目中有20个或者30个模块,岂不是要自己手动配置20多次,这种方式显然是不可取的,对理解组件化是一个不错的方式,但是真正的实际场景中,下面的方式才是主流

ext {
    //模块单独运行 设置为true
    //打包运行 设置为false
    isModuleDebug = false
    //所有项目的默认风味配置
    defaultConfigMap = [
            "compileSdk"               : 31,
            "applicationId"            : "com.study.gradleapp",
            "minSdk"                   : 21,
            "targetSdk"                : 31,
            "versionCode"              : 1,
            "versionName"              : "1.0",
            "testInstrumentationRunner": "androidx.test.runner.AndroidJUnitRunner"
    ]
    //一些三方依赖库
    libs = [
            "coreKtx": 'androidx.core:core-ktx:1.7.0',
            "appCompat": 'androidx.appcompat:appcompat:1.4.1',
            "meterial": 'com.google.android.material:material:1.5.0',
            "constraintlayout": 'androidx.constraintlayout:constraintlayout:2.1.3'
    ]
    //aar依赖
    aars = [
            "MyLibs":"libs/MyLibs-release.aar"
    ]
    //组件化项目依赖
    modules = [
            "main":":business:main"
    ]

    //每个project基本就是使用这两个插件
    setProjectDefaultConfig = { project ->
        //这里需要判断一下,app不能是一个library
        if (isModuleDebug || project.name == 'app') {
            project.apply plugin: 'com.android.application'
        } else {
            project.apply plugin: 'com.android.library'
        }
        project.apply plugin: 'kotlin-android'
        //设置project中的Android节点
        setProjectAndroidConfiguration project.android
        setProjectDependencies project.dependencies
    }

    //Android节点的配置
    setProjectAndroidConfiguration = { 
    	android {
	        android.compileSdk = defaultConfigMap.compileSdk
	
	        android.defaultConfig {
	            if (project.isModuleDebug) {
	                applicationId = defaultConfigMap.applicationId
	            }
	
	            minSdk = defaultConfigMap.minSdk
	            targetSdk = defaultConfigMap.targetSdk
	            versionCode = defaultConfigMap.versionCode
	            versionName = defaultConfigMap.versionName
	            testInstrumentationRunner = defaultConfigMap.testInstrumentationRunner
	        }
	        //
	        android.buildTypes {
	            release {
	                minifyEnabled false
	                //这里需要使用android的代理
	                proguardFiles android.getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
	            }
	        }
	        android.compileOptions {
	            sourceCompatibility JavaVersion.VERSION_1_8
	            targetCompatibility JavaVersion.VERSION_1_8
	        }
	        android.kotlinOptions {
	            jvmTarget = '1.8'
	        }
	
	        //对于sourceSet的处理
	        if(isModuleDebug){
	            android.sourceSets
	        }
        }
    }
    //设置项目的依赖配置
    setProjectDependencies = { dependencies->
        //设置了代理,就会使用dependencies中的implementation
        delegate = dependencies
        project.libs.each{ key,value->
            implementation value
        }
        //针对不同的模块,做不同的依赖配置
        if(project.name == 'app'){
            project.aars.each{ key,value->
                implementation files(value)
            }
            if(!project.isModuleDebug){
                project.modules.each{ key,value->
                    implementation project(value)
                }
            }
        }
        testImplementation 'junit:junit:4.+'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }


}
//执行setProjectDefaultConfig闭包配置
project.setProjectDefaultConfig project  

创建一个闭包setProjectDefaultConfig,就像在某个模块下的build.gradle一样,会调用apply来导入插件,使用android节点配置产品风味、dependencies依赖配置等等,都是对project的一个扩展

当完成这样的组件化配置之后,在每个节点的build.gradle中,只需要一行代码即可

apply from:"${rootProject.rootDir}/config.gradle"

看到上面肯定很多人会想,我配置的依赖,很多模块不需要,但是也依赖进去了,其实不需要考虑这些,因为依赖配置本来在打包之前,就已经完成了依赖去重

在组件化配置中,dependencies做的更多的是公共属性的配置,如果在这里做每个组件的详细配置就会使得代码变得很臃肿,其实在单独的gradle中,可以做自己特殊的依赖

# business/main/build.gradle

apply from:"${rootProject.rootDir}/config.gradle"
//做自己特殊的配置
android{
//产品风味等
}
dependencies {
    implementation project(':base:baseLib')
}

你可能感兴趣的:(技术,kotlin,android,java,gradle,组件化)