一、組件化由來
常規的項目是由一個Application模塊和若干個Library模塊組合而成。編譯一個apk需要編譯所有的模塊,如果項目比較大,或者是我只是修改了一個小功能,那么這樣編譯起來就很浪費時間。組件化就是可以動態的將library模塊切換成application模塊,單獨編譯一個library。這樣測試起來就很方便。
二、怎么樣動態切換library模塊稱為application模塊?
通過gradle來操作!
2.1 步驟一:先在項目的根目錄下建立config.gradle文件,里面是配置內容是所有項目都可以引用的:
2.2 步驟二:對module2的build.gradle文件進行修改:
if (isModule) {
//集成模式
apply plugin: 'com.android.library'
} else {
//組件模式
apply plugin: 'com.android.application'
}
//rootProject是grovey語言的關鍵字,表示能拿到根目錄下定義的所有信息
def cfg = rootProject.ext.android
def appId = rootProject.ext.appId
def v7 = rootProject.ext.dependencies
android {
compileSdkVersion cfg.compileSdkVersion
defaultConfig {
if (!isModule) {
//是組件模式,需要有appid
applicationId appId["module2"]
}
//代碼里面可以用BuildConfig.isModule來判斷當前是否是組件模式
buildConfigField("boolean", "isModule", String.valueOf(isModule))
//資源配置
sourceSets {
main {
if (!isModule) {
//組件模式,自定義AndroidManifest和java文件的路徑
manifest.srcFile 'src/main/module/AndroidManifest.xml'
java.srcDirs 'src/main/module/java', 'src/main/java'
} else {
//不是組件化,還原
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs 'src/main/java'
}
}
}
minSdkVersion cfg.minSdkVersion
targetSdkVersion cfg.targetSdkVersion
versionCode cfg.versionCode
versionName cfg.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation v7["appcompat-v7"]
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
現在就可以對Module模塊單獨編譯啦(但是不要忘記增加LaunchActivity哦)!
三、頁面路由
問題引入:如果我想要module1模塊跳轉到module2模塊,再從module2跳轉到module1,甚至是調用另一個模塊的某個方法,那該怎么辦呢?
路由框架原理是由APT幫我們創建一系列被Route注解過的類對象文件,這些文件內部是路由表,由路由地址和路由信息組合而成。
先介紹什么是APT?
3.1 APT的定義
APT(Annotation Processor Tool)注解處理器,是javac的一個工具,用來在編譯時掃描和編譯處理注解(Annotation)。你可以自己定義注解和注解處理器去搞一些事情。一個注解處理器它以Java代碼或者(編譯過的字節碼)作為輸入,生成文件(通常是Java文件)。這些生成的java文件不能修改,并且會同其手動編寫的java代碼一樣,會被javac編譯。
3.2 APT的好處
這里用ButterKnife舉例說明:
我們新建一個類:MainActivity_Binding:構造方法里面傳入MainActivity的對象,這里簡單的執行findViewById的操作:
然后我們在MainActivity里面,直接new出MainActivity_Binding的實例,那么它是不是就自動的幫我們執行了findViewById的操作?其實這也就是APT的原理,APT為我們生成了MainActivity_Binding這樣的對象,只不過用到了注解,這樣就為我們省下了很多行代碼。
3.3APT使用初體驗
3.3.1 新建一個注解,并在MainActivity類上使用該注解:
3.3.2 新建一個java模塊:testProcessor
在該模塊下新創建一個類TestProcessor 繼承AbstractProcessor:
重寫的process方法,里面的set集合就是使用注解的節點集合(類節點、屬性節點、函數節點),遍歷set集合,發現我們能拿到Route注解的MainActivity所有的信息!!!,同時結合javapoet這個庫提供的api方法,來幫我們組合新的類文件,所以我們拿到了MainActivity的所有信息(類名路徑、屬性對象、方法等等),那何愁搞不出一番大事呢?。。。
所以說APT注解處理器是路由框架的核心實現部分,在下一篇組件化開發之旅2中,我們將手寫路由框架,帶領大家揭開路由框架的神秘面紗!!!