组件化简介
一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。
组件化特点
- 使用:各种自定义的控件、工具类等重复应用的代码等等。
- 目的:复用,解耦。
- 依赖:组件之间低依赖,比较独立。
- 特点:高重用、低耦合。
- 架构定位:纵向分层(位于架构底层,被其他层所依赖)。
因此,在模块化开发的同时引入组件化将会使的工程更加的架构更加清晰。
组件化架构
• app:项目的宿主模块,仅仅是一个空壳,依赖于其他模块,成为项目架构的入口。
• baselibrary:项目的基类库,每个子模块都依赖共享公用的类和资源,防止公用的功能在不同的模块中有多个实现方式。
• module_begin:闪屏页,引导页,主页等。
• module_home:首页模块。
• module_mine:我的模块。
• module_video:视频模块。
组件的构建
1、在项目gradle.properties中需要设置一个开关
2、在各个module清单文件需要配置两个,一个作为独立项目的清单文件,一个作为库的清单文件
3、buildApp作为依赖库的清单文件,和独立项目的清单文件buildModule区别是依赖库的清单文件Application中没有配置入口的Activity
4、在build.gradle配置
5、在宿主app的build.gradle配置添加
组件间通信--ARouter
1、在app和baselibrary的gradle中分别添加
defaultConfig {
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
}
dependencies {
compile 'com.alibaba:arouter-api:1.3.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
}
2、在所有的组件module的gradle中添加
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
dependencies {
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
}
3、ARouter注册,在Application中进行注册(清单文件中进行设置application)
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initRouter(this);
}
private void initRouter(MyApplication myApplication) {
if (BuildConfig.DEBUG) {
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(myApplication);
}
@Override
public void onTerminate() {
super.onTerminate();
ARouter.getInstance().destroy();
}
}
4、在Activity或者Fragment进行设置
ARouter的使用
1、添加路由注解
@Route(path = "/mine/main") //添加路由注解 并且这里的路径需要注意的是至少需要有两级
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mine);
}
}
2、页面跳转(路由操作)
(1)无参数的页面跳转
ARouter.getInstance().build("/mine/main")
.navigation();
(2)带参数的页面跳转
ARouter.getInstance().build("/chat/main")
.withLong("key1", 666L)
.withString("key3", "888")
.navigation();
(3)在目标Activity中接收相关的参数(每个参数声明一个字段,并使用 @Autowired 标注)
@Route(path = "/mine/ClickButtonActivity")
public class ClickButtonActivity extends BaseActivity {
@Autowired(name = "name")
public String name;
@Autowired(name = "age")
public int age;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_click_button);
TextView tv_username = findViewById(R.id.tv_username);
tv_username.setText("用户名称:"+name);
Log.e("TAG", name);
Log.e("TAG", age + "");
}
}
3、声明拦截器(拦截跳转过程)
// 应用在跳转过程中处理登陆事件,就不需要在目标页重复做登陆检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 1,name = "登录拦截")
public class LoginInterceptor implements IInterceptor{
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
String groups = postcard.getGroup();
if("needLogin".equals(groups)){
if(true) {//登录判断
Log.e("你需要登录", "你需要登录");
ARouter.getInstance().build("/login/LoginActivity").navigation();
callback.onInterrupt(null);
}
}else{
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
Log.e("TestInterceptor","init");
}
}