1.爲什麼要組件化
(1)耦合嚴重:單一工程的業務之間耦合度太高,牽一髮而動全身
(2)編譯時間慢: 對工程的任何更改都必須編譯這個表格
(3)測試麻煩:功能測試和系統測試每次都要進行
(4)開發效率不高:共同開發時容易產生衝突
(5)不夠靈活:不能靈活的對業務模塊進行配置和組裝;
2.組件化介紹
組件化就是一個完整的zpp拆分成多個子模塊每個子模塊可以獨立的編譯或者運行,野結衣任意組合成另一個新的app或者模塊,每個模塊之間幾部想不依賴有可以相互交互 。
組件化的基本組成:
(1)app殼工程:就是一個空的工程,負責打包apk沒有具體的業務功能
(2)業務組件:每個業務模塊單獨出來可以形成一個獨立的工程
(3)common組件:爲每個業務模塊提供公共的組件 如 工具類 網絡類的封裝
(4)三方組件:把一系列的三方類的功能集合在一起形成的組件 如 微信支付+支付寶支付 +其他三方支付= 支付組件
3.組件化實施流程
由於是之前自己獨立開發的一個比較小的工程,所有邏輯也是自己寫的所以實施組件化起來還是比較方便的,因爲是重構以前的工程而不是重寫 所以需要一步步的進行 從開始學習開始 到最後的組件化完成 差不多一週時間 。
(1)拆解工程 提取commonLibrary模塊
我們在提取過程中要做的事情
1.爲了保證每個業務組件的版本的統一個模塊是否模塊化的開啓
添加統一的引用的gradle config.gradle 在這裏吧原來使用的引用和版本都添加進來
/**
* 全局統一配置文件
*/
ext {
//true 每個業務Module可以單獨開發
//false 每個業務Module以lib的方式運行
//修改之後需要Sync方可生效
isModule = false
//版本號
versions = [
applicationId : "com.example.componentapplication", //應用ID
versionCode : 1, //版本號
versionName : "1.0.0", //版本名稱
compileSdkVersion : 28,
buildToolsVersion : "28.0.3",
minSdkVersion : 17,
targetSdkVersion : 23,
androidSupportSdkVersion: "28.0.0",
constraintLayoutVersion : "1.1.1",
runnerVersion : "1.0.1",
espressoVersion : "3.0.1",
junitVersion : "4.12",
annotationsVersion : "24.0.0",
javaSDKVersion : 1.8,//javaSDK版本
multidexVersion : "1.0.2",
butterknifeVersion : "9.0.0",
arouterApiVersion : "1.4.0",
arouterCompilerVersion : "1.2.1",
arouterannotationVersion: "1.0.4",
gsonVersion :"2.4",
//rxjava 家族和網絡請求
rxjavaVersion :"2.1.6",
rxandroidVersion :"2.0.1",
retrofitVersion :"2.3.0",
convertergsonVersion :"2.2.0",
rxjava2adapterVersion :"2.3.0",
logginginterceptorVersion:"3.7.0",
takephotolibraryVersion :"4.0.3" ,
glideVersion :"3.8.0",
baservadapterVersion :"3.0.3",
flowlayoutVersion :"1.0.3",
permissionVersion :"1.1.0",
autosizeVersion :"1.1.2"
]
dependencies = [
"appcompat_v7" : "com.android.support:appcompat-v7:${versions["androidSupportSdkVersion"]}",
"constraint_layout" : "com.android.support.constraint:constraint-layout:${versions["constraintLayoutVersion"]}",
"runner" : "com.android.support.test:runner:${versions["runnerVersion"]}",
"espresso_core" : "com.android.support.test.espresso:espresso-core:${versions["espressoVersion"]}",
"junit" : "junit:junit:${versions["junitVersion"]}",
"support_annotations" : "com.android.support:support-annotations:${versions["annotationsVersion"]}",
"design" : "com.android.support:design:${versions["androidSupportSdkVersion"]}",
"support-v4" : "com.android.support:support-v4:${versions["androidSupportSdkVersion"]}",
"cardview-v7" : "com.android.support:cardview-v7:${versions["androidSupportSdkVersion"]}",
"recyclerview-v7" : "com.android.support:recyclerview-v7:${versions["androidSupportSdkVersion"]}",
//方法數超過65535解決方法64K MultiDex分包方法
"multidex" : "com.android.support:multidex:${versions["multidexVersion"]}",
//路由
"arouter_api" : "com.alibaba:arouter-api:${versions["arouterApiVersion"]}",
"arouter_compiler" : "com.alibaba:arouter-compiler:${versions["arouterCompilerVersion"]}",
"arouter_annotation" : "com.alibaba:arouter-annotation:${versions["arouterannotationVersion"]}",
"butterknife_compiler": "com.jakewharton:butterknife-compiler:${versions["butterknifeVersion"]}",
"butterknife" : "com.jakewharton:butterknife:${versions["butterknifeVersion"]}",
"gson" : "com.google.code.gson:gson:${versions["gsonVersion"]}",
"rxjava" : "io.reactivex.rxjava2:rxjava:${versions["rxjavaVersion"]}",
"rxandroid" : "io.reactivex.rxjava2:rxandroid:${versions["rxandroidVersion"]}",
"retrofit" : "com.squareup.retrofit2:retrofit:${versions["retrofitVersion"]}",
"convertergson" : "com.squareup.retrofit2:converter-gson:${versions["convertergsonVersion"]}",
"rxjava2adapter" : "com.squareup.retrofit2:adapter-rxjava2:${versions["rxjava2adapterVersion"]}",
"logginginterceptor" : "com.squareup.okhttp3:logging-interceptor:${versions["logginginterceptorVersion"]}",
"glide" : "com.github.bumptech.glide:glide:${versions["glideVersion"]}",
"baservadapte" : "com.zhy:base-rvadapter:${versions["baservadapterVersion"]}",
"flowlayout" : "com.zhy:flowlayout-lib:${versions["flowlayoutVersion"]}",
"permission" : "com.yanzhenjie:permission:${versions["permissionVersion"]}",
]
}
然後一定要記得 在application 的 gadle中添加
apply from: "config.gradle"
否者會報 類似這種的錯誤
ERROR: Cannot get property 'versions' on extra properties extension as it does not exist
然後就是修改commonlibrary的gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.versions.compileSdkVersion
buildToolsVersion rootProject.ext.versions.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.versions.minSdkVersion
targetSdkVersion rootProject.ext.versions.targetSdkVersion
versionCode rootProject.ext.versions.versionCode
versionName rootProject.ext.versions.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//Arouter路由配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
includeCompileClasspath = true
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
compileOptions {
targetCompatibility rootProject.ext.versions.javaSDKVersion
sourceCompatibility rootProject.ext.versions.javaSDKVersion
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//把implementation 用api代替,它是對外部公開的, 所有其他的module就不需要添加該依賴
api rootProject.ext.dependencies["support_annotations"]
api rootProject.ext.dependencies["junit"]
//MultiDex分包方法
api rootProject.ext.dependencies["multidex"]
//Arouter路由
annotationProcessor rootProject.ext.dependencies["arouter_compiler"]
api rootProject.ext.dependencies["arouter_api"]
api rootProject.ext.dependencies["arouter_annotation"]
//解析
api rootProject.ext.dependencies["gson"]
//rxjava和網絡
api rootProject.ext.dependencies["rxjava"]
api rootProject.ext.dependencies["rxandroid"]
api rootProject.ext.dependencies["retrofit"]
api rootProject.ext.dependencies["convertergson"]
api rootProject.ext.dependencies["rxjava2adapter"]
api rootProject.ext.dependencies["logginginterceptor"]
//圖片加載
api rootProject.ext.dependencies["glide"]
//黃油刀
annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]
api rootProject.ext.dependencies["butterknife"]
//權限
api rootProject.ext.dependencies["permission"]
api 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
implementation project(path: ':uilibrary')
}
把原來自己原來封裝的baseActivity 、網絡等一些內容移動進來
這樣我們對commonLib的封裝就完成了
2.業務模塊的封裝
每個不同的app都有着自己不同封裝,這個是需要根據具體的邏輯來的 就讓我們先看一下原理的界面來抽出不同的業務模塊。
先看具體界面
最終一共分爲五個模塊、
home:入口+首頁模塊
answer:答題測試模塊
shop:積分商城模塊
me:個人中心模塊
commonActiivty:需要在四個模塊中都需要用到的模塊 如登錄註冊 等
業務模塊遇到的問題
1.butterknife問題
application的gradle中添加 classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
需要在每個模塊的gradle中添加
apply plugin: 'com.jakewharton.butterknife
dependencies {
annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]
}
2.Arouter配置問題
一定要早每一個module中都要配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
includeCompileClasspath = true
}
}
3.application和library轉換問題
在module的gradle中添加根據config中多的isModule判斷是集成模式還是單個運行模式
if (Boolean.valueOf(rootProject.ext.isModule)) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
4.資源文件問題
在給資源文件命名的時候一定要以當前的module爲前綴
5.不同xml問題
根據模式判斷加載那個xml
在module/AndroidManifest.xml'下面要記得配置入口啊
sourceSets {
main {
if (Boolean.valueOf(rootProject.ext.isModule)) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
java {
//排除java/debug文件夾下的所有文件
exclude '*module'
}
}
}
最後上傳組件化demo: