参考文章:Android 多模块多组件开发 - 打造属于自己的路由
开源库地址:https://github.com/HCDarren/DRouter
为什么使用DRouter
在我们项目开发中很多的时候是需要多人开发,在多人开发中,不同的开发人员负责不同的模块进行开发,如有的人负责首页模块,有人负责分享模块等等,这个时候为了可以方便团队合作开发,我们可以选择使用模块开发,使用Model来进行开发。
通常来讲一个项目是由项目总监/大佬来搭建最底下的两层运行时架构、代码架构。
like this
这两层架构我就不多说了(其实自己也不太懂,还没到那个地步...希望有懂哥能介绍下)
然后我们先新建几个模块就像这样新建一个model
在这里我创建了3个模块,一个home、一个activity、一个personal,总共三个个模块,然后再创建一个运行时架构base,一个代码架构code。
依赖关系就像上图一样,app依赖home、personal、activity,这三个模块依赖运行时架构base,base依赖代码架构code。
这样依赖关系搭建好了。
在日常的开发中我们很常见的一种需求就是每逢过节搞活动我们都要有推出新的板块,这个时候我们可以新建新的Model,但有可能需要我们用到其他模块的内容,最常见就是跳转,那怎么办处理,最简单就是直接依赖,当这些模块多起来的时候,不同模块进行依赖那么就会出现下面的这种情况
当某一天需要我们删掉某一个模块,那个时候你就会方向,很多模块都是依赖这个模块,所有依赖这个模块的都需要改动,那一个工程量想想都哈人。
那么该如何解决呢?
DRouter的使用
这个时候我们可以选择使用路由框架来解决这种问题,就是说所有模块都是选择依赖一个路由模块,通过这个路由模块来进行分发进行跨模块通信。
这里我是使用github上的HCDarren/DRouter这一个路由框架,你还可以选择ARouter这个框架。
DRouter使用的注意点
首先使用可以看一下这个开源库的Read.ME和上面的参考文章。
我这里主要说一下注意点。
依赖问题
这里DRouter用到的是3个主要模块:drouter-api,drouter-base,drouter-compiler这3个模块,你可以下载zip包后将这3个模块导入到你的项目中,然后将最底层的模板(在这里就是lib-code)去依赖drouter-api这一个模块。还需要主要一点就是依赖的问题,先看一下图
注意到圈住的地方没有,这里一般系统的依赖是使用implementation的,但是在这里我们选择的依赖方式是compile,不仅是这一个模块的依赖,其他模块的依赖尽量是选择compile,不然在使用@Action这一个注解可能会发现没有找到,原因是什么我也不太清楚。
path问题
在使用@Action这一个注解时候可能会有一点问题,先看一下基本的使用代码
这个是一个被跳转的模块lib-activity
//path 路径, thread指定线程,extraProcess 开启进程
@Action(path = "libactivity/activity",threadMode = ThreadMode.MAIN,extraProcess = true)
public class ActivityAction implements IRouterAction {
@Override
public RouterResult invokeAction(Context context, Map<String, Object> requestData) {
//可以做任何操作
Intent intent = new Intent(context,ActiveActivity.class);
context.startActivity(intent);
return new RouterResult.Builder().success().object("100").build();
}
}
在这个lib-activity中gradle中添加
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
arguments = [moduleName: project.getName()]
}
}
}
dependencies{
annotationProcessor project(':drouter-compiler')
}
其实这里的目的是为了让这个模块注册到DRouter中(暂且这么理解,如果看了源码其实发现,就是通过扫描DEX文件来看有没有这一个类,有时间的话可以看一下源码)
然后在要跳转的类(在这里是lib-home模块)
public void jumpActivity(View view){
//跳转到活动页
DRouter.getInstance().action("libactivity/activity")
.context(this)
.invokeAction();
}
这就是一个基本的使用,但是这里有一个坑就是这个path问题,首先这个path的格式一定是xxx/xxx这样的,一定要有"/",然后前面的是模块名字,后面则是自己命名跳转名。第一个坑就出在模块名字,我这里要被跳转的模块时lib-activity,所以我的path是path=lib-activity,但是就是跳转不成功,开启了debug模式会弹一个toast,说是Please check to the action name is correct....”,问题出在这里了,后面看了源码发现
moduleName = moduleName.replaceAll("[^0-9a-zA-Z_]+", "");
也就说正确路径应该为path=“libactivity/activity”,当然可能这样还是不能成功,还有一个解决方法,可以看一下我上一篇的文章。
这样就是就可以跨模块通信了,所有跳转都会先跳转到相应的IRouterAction中的invokeAction()方法中,然后再在里面做具体的操作。
拦截器的使用
这里可以看一下文档,是怎么使用的
// priority 优先级越高,拦截器执行越优先
@Interceptor(priority = 18)
public class CircleInterceptor implements ActionInterceptor {
@Override
public void intercept(ActionChain chain) {
ActionPost actionPost = chain.action();
// 圈子详情页必须是要登录,如果没有登录即可拦截跳转到登录页面,否则继续往下执行。
if (chain.actionPath().equals("circlemodule/test")) {
Toast.makeText(actionPost.context, "拦截圈子,跳转到登录", Toast.LENGTH_LONG).show();
// 跳转到登录页面
DRouter.getInstance()
.action("login/action")
.context(actionPost.context)
.invokeAction();
// 这个方法调用后便会拦截整条链
chain.onInterrupt();
}
// 继续向下转发
chain.proceed(actionPost);
}
}
看一下这个是不是很像Okhttp中的自定义拦截器使用,其实就是作者参考okhttp的源码写的,所以说使用和okhttp的自定义拦截器一样使用,所有跳转都是会走一遍这个ActionChain,直到没有拦截才会走自己的。
模块的配置
new新的model中,需要我们将模块中的gradle配置同一管理(包括app模块),原因是因为不同人开发不同的模块,我们之间使用的gradle版本不一样,sdk版本不一样等,依赖不同的第三方框架,不同的框架版本等等,所以我们一般将用一个gradle进行配置,通常是放在底层的模板中(在这里是code层),他们的配置都是用同一套,这样易于管理,当然选择哪一个框架,哪一个版本就看你们的大佬怎么选择了,至于如何统一配置这里就不展开了,自行百度一下就有了。
总结
这一个开源库还是值得看一下源码学习一下的,但是能不能用到项目中我是打一个问号的,如果要用的话我推荐是用ARouter这一个路由框架,大致使用差不多。
之前还收藏了一位老哥关于ARouter的文章,还打算后面慢慢看的,没想到删除了,老哥人也没了,真的可惜,借此机会自己来研究一下。