组件化由于它的解耦,独立,开发效率已经成为了被广泛使用的项目架构了,特别是大项目重构的首选,今天就一起来看看组件化开发。
- 说说模块化和组件化
- 说说组件间通信是怎么做的
- Application生命周期分发是怎么做的
说说模块化和组件化
模块化也就是可以把app
中的一些功能分成不同的模块,在Androidstudio
里面以不同的module展示,然后模块之间会有相互依赖的关系,但是高耦合度就意味着虽然分成了不同的模块,但是还是一个整体的项目,拆分的意义就不大了。
所以这时候就需要对项目进行组件化
,组件化的最大差别就是在于他的解耦
,让每个模块可以独立作为app,模块之间没有直接的依赖关系,单独的基础模块可以供每个业务模块使用。这样带来的好处就是:
- 加快了
编译速度
,每个业务功能都是单独的工程,可以独立编译 - 提高
协作效率
,独立化使得每个组件的开发都相对独立,互不影响 功能重用
,组件化之后,以后做新项目就能很快开展起来,一些基础组件都可以直接用起来,比如网络组件等
说说组件间通信是怎么做的
- 页面跳转的话,比如
Activity,Fragment
等跳转都是通过ARouter
实现,ARouter是一种路由框架,之前的文章也讲过,通过apt生成path
和activity
的关系代码,然后进行页面跳转。 - 组件间通信的话,由于组件之前是没有耦合度的,所以需要单独新建一个组件用于
暴露服务接口
,然后两个需要通信的模块都依赖这个通信接口组件
,一个实现
所需要的服务接口,一个 去调用
接口,这样就完成了通信。至于接口的实现注入还是有ARouter
来完成。这样就在保证了组件之间无关联的前提下进行了通信。
- 接口组件module_export
public interface INewsService extends IProvider {
NewsInfo getNews();
}
public class CartServiceUtil {
public static INewsService getService(){
return (INewsService) ARouter.getInstance().build("/news/service").navigation();
}
public static NewsInfo getNews(){
return getService().getNews();
}
}
- 通信组件module_news,实现接口
//依赖接口组件
implementation 'module_export'
@Route(path = "/news/service")
public class NewsServiceImpl implements INewsService {
@Override
public NewsInfo getNews() {
//这里实际项目中 应该是 请求接口 或查询数据库
NewsInfo newsInfo = new NewsInfo();
return newsInfo;
}
@Override
public void init(Context context) {
//初始化工作,服务注入时会调用
}
}
- 通信组件module_home,调用接口
//依赖接口组件
implementation 'module_export'
CartServiceUtil.getNews()
Application生命周期分发是怎么做的
这个问题其实是问的,Application
的生命周期管理肯定是放在主模块上的,比如onCreate
,但是其他的业务模块也有需要在Application
的生命周期中需要初始化的内容,而且由于解耦,业务模块和主模块是没有联系的,那么作为业务模块,该怎么获得Application
生命周期呢?
第一个方法是通过反射,就是在主 模块中反射获取子模块的初始化对象,然后调用其初始化方法。
代码语言:javascript复制public static String[] moduleInits = {
moduleOneInit,
moduleTwoInit
};
public interface BaseAppInit {
boolean onInit(Application application);
}private void initModuleHighPriority(){
for (String init: ModuleConfig.moduleInits){
try {
Class<?> clazz = Class.forName(init);
BaseAppInit appInit = (BaseAppInit) clazz.newInstance();
appInit.onInitHighPriority(this);
}
catch (ClassNotFoundException | IllegalAccessException | InstantiationException e)
{
e.printStackTrace();
}
}}
虽然这样可以实现,但还是一个笨方法,因为还是要去获取业务模块的类名,而且反射毕竟效率很低,影响性能
。
其实我们可以借鉴Arouter
的实现方式,通过apt
,也就是注解处理工具,在编译期间去获取所有注解过的类,然后调用他们所实现接口的初始化方法。这里有个库大家可以借鉴下:https://github.com/hufeiyang/Android-AppLifecycleMgr
使用代码贴下:
代码语言:javascript复制
@AppLifecycle
public class CartApplication implements IApplicationLifecycleCallbacks {
public Context context;
/**
* 用于设置优先级,即多个组件onCreate方法调用的优先顺序
* @return
*/
@Override
public int getPriority() {
return NORM_PRIORITY;
}
@Override
public void onCreate(Context context) {
//可在此处做初始化任务,相当于Application的onCreate方法
this.context = context;
Log.i("CartApplication", "onCreate");
}
//...
}
//主工程 MyApplication
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ApplicationLifecycleManager.init();
ApplicationLifecycleManager.onCreate(this);
}
}
参考
https://juejin.im/post/6881116198889586701