一、簡介
基於模塊化。有一個主工程(殼工程)和多個組件(module)。開發時每個組件都是application,打包發佈時每個組件都作爲library。
關於模塊化:
模塊化是AndroidStudio中引進的概念,主要分爲application和library兩種格式。將工程中共享部分和各個業務模塊,拆分成多個module,實現代碼和業務上的解耦。是組件化的基礎。
二、存在的意義
- 將公共依賴庫以及各個業務模塊代碼徹底解耦,使得組件關係更加清晰。
- 擺脫了修改一個模塊需要編譯這個工程的弊端,加快了編譯速度。
三、實現步驟
在組件化開發中,實現難點主要在於
1.組件間界面的跳轉以及數據的傳遞和共享
2.開發和發佈環境如何快速切換,畢竟application和library在gradle及AndroidManifest的配置上有
3.1 對於路由的處理
我們可以使用Intent跳轉,但是考慮到Intent需要依賴library硬編碼,我們這裏使用ActivityRouter作爲項目路由,在app包下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void textOnClick(View view) {
Routers.open(MainActivity.this, Uri.parse("modularization://url_path/1/字符串"));
}
}
3.2 對於usermodule包在開發中作爲library與application切換
首先我們需要在項目根目錄gradle.properties下定義變量用來區分usermodule是作爲library還是application
IsBuildSignle=true
另外在usermodule作爲獨立application的時候,app包不需要依賴於usermodule,所以需要在app包的Gradle中處理成
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.common.modularization_master"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
if (!IsBuildSignle.toBoolean()){
compile project(':usermodule')
}
compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
}
同時在usermodule不作爲獨立application的時候,manifest不需要程序入口,所以對於usermodule我們需要定義兩套manifest。在usermodule的Gradle中我們處理成
if(IsBuildSignle.toBoolean()){
apply plugin:'com.android.application'
}else{
apply plugin:'com.android.library'
}
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets{
main{
if(IsBuildSignle.toBoolean()){
manifest.srcFile 'src/main/AndroidManifest.xml'
// java.srcDirs += "src/main/debug/java/";
}else{
manifest.srcFile 'src/library/AndroidManifest.xml'
}
}
}
//代碼靜態檢查,避免資源混淆
// resourcePrefix "usermodule"
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
annotationProcessor 'com.github.mzule.activityrouter:compiler:1.1.7'
}
最後我們可以在usermodule作爲library中接收來自於app包的數據:
@Modules({"usermodule"})
@Module("usermodule")
@Router("url_path/:id/:title")
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.usermodule_activity_main);
int id = 0;
String title = null;
if (getIntent().getExtras() != null) {
id = getIntent().getExtras().getInt("id", 0);
title = getIntent().getExtras().getString("title", null);
}
((TextView) findViewById(R.id.tv_usermodule)).setText("This is user module:" + "id:" + id + ",title:" + title);
}
}