组件化开发——Android studio gradle配置文件统一管理
在组件化开发中尽可能满足以下要求1:
- 添加新组件必须简单
- 维护组件配置必须简单
所以简化gradle配置文件是很有必要的,通过如下方式可以省略module中gradle大量代码
第一步:新建统一配置文件
在项目根目录中新建统一配置文件 config.gradle
(名字可自定义)
代码核心:
- 使用
subprojects
和hasProperty
统一配置所有子build.gradle
中android
字段公有内容 - 使用
project.projectDir.name
获取不同build.gradle
所在module名称,以此可区分不同build.gradle
中android
字段差异代码 - 打包管理
//使用方法 在项目根目录build.gradle顶部添加-> apply from: "config.gradle"
ext {
//*************************app Module配置管理**************************
base = [compileSdkVersion: 28,
minSdkVersion : 19,
targetSdkVersion : 28,
buildToolsVersion: '28.0.3']
app = [appName: "Test",
apkName: "tomcat"]
xxx = [appName: "xxx",
apkName: "xxx"]
}
def getModuleInfo = {
String name, String k ->
Object o = null
Map<String, Object> s
if (ext.has(name)
&& (s = ext.get(name)).containsKey(k)) {
o = s.get(k)
} else {
s = ext.get("base")
if (s.containsKey(k)) {
o = s.get(k)
}
}
o
}
subprojects {
afterEvaluate { project ->
def plugins = getPlugins()
def isApp = plugins.hasPlugin("com.android.application")
def isAppLib = plugins.hasPlugin("com.android.library")
if (isApp || isAppLib) {
android {
compileSdkVersion base .compileSdkVersion
buildToolsVersion base .buildToolsVersion
defaultConfig {
minSdkVersion base .minSdkVersion
targetSdkVersion base .targetSdkVersion
consumerProguardFiles 'consumer-rules.pro'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
abiFilters 'armeabi', 'armeabi-v7a'
}
if (isApp) {
flavorDimensions "channel"
}
}
dexOptions {
javaMaxHeapSize "4g"
preDexLibraries = false
}
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
lintOptions {
abortOnError false
//即使报错也不会停止打包
checkReleaseBuilds false
//打包release版本的时候进行检测
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
jniLibs.srcDir 'libs'
jni.srcDirs = [] //disable automatic ndk-build
}
}
buildTypes {
debug {
minifyEnabled false
debuggable true
if (isApp) {
manifestPlaceholders = [APP_NAME:getModuleInfo(project.getName(), "appName") + "debug(${defaultConfig.versionName})", PROVIDER: "${defaultConfig.applicationId}.fileProvider"]
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} else {
consumerProguardFiles 'proguard-rules.pro'
}
}
release {
debuggable false
minifyEnabled true//启用Proguard --正常应该是true
zipAlignEnabled true //是否启用zipAlign压缩
if (isApp) {
shrinkResources true //是否清理无用资源,依赖于minifyEnabled
manifestPlaceholders = [APP_NAME: getModuleInfo(project.getName(), "appName"), PROVIDER: "${defaultConfig.applicationId}.fileProvider"]
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} else {
consumerProguardFiles 'proguard-rules.pro'
}
}
}
if (isApp) {
// 渠道配置
productFlavors {
other {}
xiaomi {}
huawei {}
_360 {}
wandoujia {}
baidu {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
}
// 多渠道打包配置名称
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def type = variant.buildType.name
outputFileName = getModuleInfo(project.getName(), "apkName")+ "_" + variant.flavorName + '_' + type + "_" + "${defaultConfig.versionName}" + '.apk'
if (type != "debug") {
variant.getPackageApplicationProvider().get().outputDirectory = new File(project.rootDir.absolutePath + "/apk/" + variant.flavorName)
}
}
}
}
}
if (project.hasProperty('dependencies')) {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.61"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
debugImplementation "com.squareup.leakcanary:leakcanary-android:1.6.2"
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:1.5.4"
testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:1.5.4"
annotationProcessor 'androidx.annotation:annotation:1.1.0'
}
}
} else if (plugins.hasPlugin("java-library")) {
}
}
// 重复依赖不同版本处理
// project.configurations.all {
// resolutionStrategy.eachDependency { details ->
// if (details.requested.group == 'androidx.core') {
// details.useVersion "1.3.0"
// }
// }
// }
}
第二步:项目根build.gradle
在项目根build.gradle
文件头部添加
apply from: "config.gradle"
......
第三步:子build.gradle
子build.gradle
(module中的build.gradle)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
defaultConfig {
versionCode 1
versionName "1.0"
applicationId "com.tomcat.baseframe"
}
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
defaultConfig {
versionCode 1
versionName "1.0"
}
}
dependencies {
}
参考
Jeroen Mols:Modularization - Lessons learned ↩︎