一、简介
基于模块化。有一个主工程(壳工程)和多个组件(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);
}
}