AucFrame 往期文章:php
「AucFrame 之统一管理 Gradle」源码传送门java
首先,咱们再看一遍 AucFrame 的架构图。android
咱们从下开始往上搭建,在根目录建立 lib
文件夹,在项目中新建一个 Android Library
类型的 base
module,而后删除其中的 base.iml
,由于不删除 base.iml
文件的话会影响后续的移动,把 androidTest
以及 test
测试目录删了也没事,而后咱们把 base
文件夹移入到 lib
中,最后咱们修改 setting.gradle
文件中的 ':base'
为 :lib:base
,最后点击 Gradle 的同步便可,最终会在 lib
下生成 lib.iml
,base
下生成 lib-base.iml
表示成功,结果以下所示:git
一样的方式,咱们建立 :lib:common
,接下来配置他们的依赖关系。github
咱们能够看到 base
和 common
的 build.gralde
简直一毛同样,这样咱们是否能够把他们都抽出去呢,答案是确定的。api
咱们在项目根目录建立 buildLib.gradle
文件,表明全部 lib
类型的模块均可以使用它,咱们放入公共内容便可,具体以下所示:微信
apply {
plugin "com.android.library"
plugin "kotlin-android"
plugin "kotlin-android-extensions"
}
android {
compileSdkVersion Config.compileSdkVersion
defaultConfig {
minSdkVersion Config.minSdkVersion
versionCode Config.versionCode
versionName Config.versionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
复制代码
能够看到,咱们使用到了 Config.groovy
中的属性,这样方便全部 lib 的版本都一致,说到版本一致,那么咱们还要统一第三方库的依赖,很简单,咱们在 Config.groovy
中建立依赖库的配置,现在它长这样:架构
class Config {
static applicationId = 'com.blankj.aucframe' // TODO: MODIFY
static appName = 'AucFrame' // TODO: MODIFY
static compileSdkVersion = 27 // TODO: MODIFY
static minSdkVersion = 21 // TODO: MODIFY
static targetSdkVersion = 27 // TODO: MODIFY
static versionCode = 1_000_000 // TODO: MODIFY
static versionName = '1.0.0'// E.g. 1.9.72 => 1,009,072 // TODO: MODIFY
static kotlin_version = '1.3.10'
static support_version = '27.1.1'
static leakcanary_version = '1.6.3'
static depConfig = [
plugin : [
gradle: "com.android.tools.build:gradle:3.3.0",
kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version",
],
support : [
appcompat_v7: "com.android.support:appcompat-v7:$support_version",
design : "com.android.support:design:$support_version",
multidex : "com.android.support:multidex:1.0.2",
constraint : "com.android.support.constraint:constraint-layout:1.1.3",
],
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",
utilcode : "com.blankj:utilcode:1.25.0",
free_proguard: "com.blankj:free-proguard:1.0.1",
swipe_panel : "com.blankj:swipe-panel:1.1",
leakcanary : [
android : "com.squareup.leakcanary:leakcanary-android:$leakcanary_version",
android_no_op : "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version",
support_fragment: "com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version",
],
]
}
复制代码
接下来就是让 base
和 common
应用它们了,咱们往 base
的 build.gradle
写入以下完整内容:app
apply {
from "${project.rootDir.path}/buildLib.gradle"
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
api Config.depConfig.utilcode
api Config.depConfig.free_proguard
api Config.depConfig.swipe_panel
api Config.depConfig.support.appcompat_v7
api Config.depConfig.support.design
api Config.depConfig.support.multidex
api Config.depConfig.support.constraint
api Config.depConfig.kotlin
compileOnly Config.depConfig.leakcanary.android_no_op.dep
}
复制代码
因为咱们 common
模块是依赖 base
的,因此 common
的配置以下所示:框架
apply {
from "${project.rootDir.path}/buildLib.gradle"
}
dependencies {
api project(":lib:base")
}
复制代码
写入的内容都比较简单,我就不一一解释了,下面咱们来管理 feature。
如今咱们往 base
模块放两个基础类 ———— BaseApplication
和 BaseActivity
,在 common
中放入两个公共类 ———— CommonApplication
和 CommonBackActivity
以及一些公共资源,具体请查阅源码,接下来让咱们来管理 frature。
再看一遍架构图,咱们能够发现 feature 中每一个 feature 中都存有 app、pkg(、export) 模块,咱们自底向上来一步步操做,如今咱们在根目录建立 feature 目录,在 feature 目录下建立 feature0 及 feature1 目录,和建立 base
相似,咱们在 feature0 和 feature1 中建立 export
模块,注意两个 feature 中的 export
包名要区分开,我这里分别是 com.blankj.feature0.export
、com.blankj.feature1.export
,创建完以后的 setting.gradle
文件以下所示:
include ':app', ':lib:base', ':lib:common',
':feature:feature0:export', ':feature:feature1:export',
复制代码
因为 export
是依赖 common
的,因此两个 export
的 build.gradle
以下所示:
apply {
from "${project.rootDir.path}/buildLib.gradle"
}
dependencies {
api project(":lib:common")
}
复制代码
如今咱们 gradle
同步一下,能够发现两个 export
已经被添加进来了。
咱们以相同的方式建立两个 pkg
,包名分别是 com.blankj.feature0.pkg
、com.blankj.feature1.pkg
,创建完后的 setting.gradle
文件以下所示:
include ':app', ':lib:base', ':lib:common',
':feature:feature0:export', ':feature:feature1:export',
':feature:feature0:pkg', ':feature:feature1:pkg'
复制代码
pkg
咱们暂时只依赖各自的 export
,后面咱们会再改为全量依赖 export
,因此 :feature:feature0:pkg
的 build.gradle
以下所示:
apply {
from "${project.rootDir.path}/buildLib.gradle"
}
dependencies {
api project(":feature:feature0:export")
}
复制代码
:feature:feature1:pkg
的 build.gradle
同理。
gradle
同步一下,能够发现两个 pkg
已经被添加进来了,如今咱们在 :feature:feature0:pkg
中添加一个 Feature0Activity
,以及在 :feature:feature1:pkg
中添加一个 Feature1Activity
,具体请参看源码。
pkg
上层就是 mock
层了,由于这层是可选的,咱们暂时先跳过,后面咱们用到的时候再来搞定它,那么如今就只剩下各个 app
了,首先,咱们利用相似和 buildLib.gradle
类似的方式,在根目录建立公共的 buildApp.gradle
文件,内容以下所示。
apply {
plugin "com.android.application"
plugin "kotlin-android"
plugin "kotlin-android-extensions"
}
android {
defaultConfig {
minSdkVersion Config.minSdkVersion
versionCode Config.versionCode
versionName Config.versionName
applicationId Config.applicationId + suffix
targetSdkVersion Config.targetSdkVersion
multiDexEnabled true
resValue "string", "app_name", Config.appName + suffix
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/*'
}
dexOptions {
preDexLibraries true
javaMaxHeapSize "8g"
maxProcessCount 8
dexInProcess = true
}
}
dependencies {
// LeakCanary
debugImplementation Config.depConfig.leakcanary.android
debugImplementation Config.depConfig.leakcanary.support_fragment
releaseImplementation Config.depConfig.leakcanary.android_no_op
}
def getSuffix() {
if (project.path == ":feature:launcher:app") return ""
return project.path.replace(":", "_").substring(":feature".length(), project.path.length() - ":app".length())
}
复制代码
这样咱们在每一个 app 中的 build.gradle
均可以使用这些公共属性,细心的朋友应该能够看到我这边除了 launcher
之外,每一个 applicationId
都是都是带有 feature 的模块名后缀的,具体方法就是 getSuffix(),方便咱们在手机上同时装多个应用。
咱们先删除根目录下的 app 目录,在 feature0 和 feature1 中以相同的方式建立两个 app
,包名分别是 com.blankj.feature0.app
、com.blankj.feature1.app
,创建完后的 setting.gradle
文件以下所示:
include ':lib:base', ':lib:common',
':feature:feature0:export', ':feature:feature1:export',
':feature:feature0:pkg', ':feature:feature1:pkg',
':feature:feature0:app', ':feature:feature1:app'
复制代码
app
是只依赖各自的 pkg
,因此 :feature:feature0:app
的 build.gradle
以下所示:
apply {
from "${project.rootDir.path}/buildApp.gradle"
}
dependencies {
api project(":feature:feature0:pkg")
}
复制代码
:feature:feature1:app
的 build.gradle
同理。
同步一下项目能够发现两个 app
也被编译到了项目中,在可运行 app 列表中已经有了 feature0-app
和 feature1-app
,以下图所示:
如今咱们在 :feature:feature0:app
中添加一个 Feature0App
,以及在 :feature:feature1:app
中添加一个 Feature1App
,具体请参看源码,而后把设置各自的 AndroidManifest.xml
,我这里以 :feature:feature0:app
中的为例:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.blankj.feature0.app">
<application android:name="com.blankj.feature0.app.Feature0App" android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
<activity android:name="com.blankj.feature0.pkg.Feature0Activity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
复制代码
能够发现,咱们加入了 Feature0Activity
做为启动页,这样即可快速调试它,同理,:feature:feature1:app
的 AndroidManifest.xml
也是如此,此时咱们即可单独运行一下它们了,因为他们的 applicationId
是不一样的,因此二者能够同时安装。
下面,咱们和以前上述同样的方式来建立最顶层的 :feature:launcher:app
模块,目前咱们让它依赖 :feature:feature0:pkg
和 :feature:feature1:pkg
模块,后续咱们会让它支持动态化配置,其 build.gradle
以下所示:
apply {
from "${project.rootDir.path}/buildApp.gradle"
}
dependencies {
api project(":feature:feature0:pkg")
api project(":feature:feature1:pkg")
}
复制代码
把其加入到 setting.gradle
中,同步一下 gradle,会发现可运行 app 中多了个 launcher-app
,咱们建立一个 LauncherApp
,这里咱们假设 app 的入口就在 feature0 中,故配置 :feature:launcher:app
中的 AndroidManifest.xml
以下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.blankj.feature0.app">
<application android:name="com.blankj.feature0.app.Feature0App" android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
<activity android:name="com.blankj.feature0.pkg.Feature0Activity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
复制代码
咱们把三个应用都装到手机上,应用名分别为 AucFrame
、AucFrame_feature0
、AucFrame_featrue1
,到此,咱们统一管理 Gradle 已结束。
欢迎加入个人知识星球「基你太美」,我会在星球中分享 AucFrame 框架、大厂面经、AndroidUtilCode 更详尽的说明...一切我所了解的知识,你能够经过支付进入个人星球「基你太美」进行体验,加入后优先观看星球中精华的部分,若是以为星球的内容对自身没有收益,你能够自行申请退款退出星球,也不必加我好友;若是你已肯定要留在个人星球,能够经过扫描以下二维码(备注:基你太美+你的星球昵称)加我我的微信,方便我后续拉你进群(PS:进得越早价格越便宜)。