一. 基本介绍
借此机会分享一下自己从刚入门到现在, 在开发架构方面的一些心路历程最终我会把这部分代码进行开源, 以后也会对其进行维护但目前尚在测试中所以并未发布正式版本我们可以先把代码下载下来进行了解, 如果有什么问题可以随时 Issues, 这也将是我的第一个开源库, 希望能帮到大家
该库所涉及到的类大概在 30 个左右, 源码并不多相信我们都能读懂里面的内容, 这里罗列一下源码中所涉及到的一些知识点:
(1) 编译时注解自动生成 ModuleAction 和 Intercepter
(2) 线程线程池线程同步异步和 Handler
(3) 责任链模式享元模式策略模式模板模式
作为一个多模块的路由通信库, 相信它已支持了所有跨模块通信的使用场景, 功能介绍如下:
(1) 支持依赖注入, 可单独作为依赖注入框架使用
(2) 支持线程切换和调度 (原始线程, 主线程, 同步, 异步)
(3) 支持多模块工程下的所有跨模块通信使用场景
(4) 支持添加多个拦截器, 可根据优先级自定义拦截顺序
(5) 支持权限和网络检测登录拦截跳转和数据埋点等功能
笔者阅读了大量的开源库源码, 本库的所有代码思想都来自其中, 很感激这些大牛的开源和分享精神:
- (1) ARouter
- (2) butterknife
- (3) okhttp
- (4) EventBus
- (5) RxJava
- (6) retrofit
二. 架构的演变之路
首先分享一下自己从刚入门到现在, 在开发架构方面的一些心路历程, 从刚开始踏上程序这条不归路 (人生就是一条不归路), 想想已经是好几个年头, 中间经历过提升迷茫和进阶, 也经历过从不自信到自信自满到自负刚开始一个人在小公司小打小闹, 是这个样子的:
那个时候所有的类都是写在一个包下面的, 所有的 Activity 都是继承自系统下的 android.app.Activity, 网络框架都是直接用的 android-async-http 所以加班挺严重, 一方面是自己能力经验还不够, 另一方面是没有架构的情况下很多代码都是反复冗余的毕业后去了一家上市公司, 多人团队协作开发所以就改变了一些:
这个时候已经有所提升了, 所有的 Activity 也不是直接继承自 android.app.Activity 了, 也不再是直接使用 android-async-http 所以开发的日子自然舒坦了一些一方面是经验能力上去了遇到问题能马上解决, 另一方面基于架构开发很多代码不用反复写后期也便于维护, 最主要的是大公司人多一些, 之前是一个人干四个人的活, 现在四个人干一个人的活随着开发人员的越来越多, 还有就是基本每逢过节都要做一些活动, 等活动过后这些代码和资源就要删除, 而且每两个月就得迭代一个新的版本, 所以变得越来越复杂起来后来就衍生出了很多像热更新插件化多模块多组件开发等等当然刚开始的多模块多组件并未基于路由, 是蜘蛛网的状态
会有这么乱吗? 随着业务逻辑更加复杂的情况下应该会更乱, 因为功能模块都是各自存在于自己的 Module 中, 但是可能在开发的过程中 Module1 得调用 Module2 的代码, 这个时候如果是直接添加依赖那么肯定就会有这么乱了接下来看下基于路由情况下的多模块多组件开发:
三. DRouter 基本使用
在需要跨模块通信的 Module 中添加依赖和配置
- defaultConfig {
- ......
- javaCompileOptions {
- annotationProcessorOptions {
- arguments = [moduleName: project.getName()]
- }
- }
- }
- dependencies {
- .......
- annotationProcessor project(':drouter-compiler')
- }
在 Module 中创建需要执行的 Action
- // path 必须是以在 gradle 中配置的 moduleName + "/" 开头, 否则编译通不过
- // threadMode 支持 POSTING MAINBACKGROUNDASYNC 默认情况下是 POSTING(原始线程)
- @Action(path = "login/action", threadMode = ThreadMode.MAIN)
- public class LoginAction implements IRouterAction {
- @Override
- public RouterResult invokeAction(Context context, Map<String, Object> requestData) {
- // 通信执行方法支持所有场景, 启动 Activity,Service,Provider, 弹框, 缓存数据, 获取 Fragment 等等等等
- Intent intent = new Intent(context, LoginActivity.class);
- intent.putExtra("key", (String) requestData.get("key"));
- context.startActivity(intent);
- return new RouterResult.Builder().success().object(100).build();
- }
- }
初始化 SDK
- public class BaseApplication extends Application{
- @Override
- public void onCreate() {
- super.onCreate();
- // 开启 debug
- DRouter.openDebug();
- // 初始化且只能初始化一次, 参数必须是 Application
- DRouter.getInstance().init(this);
- }
- }
可在任意 Module 中执行跳转
- // 根据 action 查询只执行对应方法, 不处理返回回调, 参数携带随意
- DRouter.getInstance()
- .action("login/action")
- .context(this)
- .param("key", "value")
- .invokeAction();
- // 根据 action 查询执行对应方法, 并处理返回回调
- DRouter.getInstance()
- .action("circlemodule/test")
- .context(this)
- .invokeAction(new ActionCallback() {
- @Override
- public void onInterrupt() {
- Log.e("TAG", "被拦截了");
- }
- @Override
- public void onResult(RouterResult result) {
- // 注意该方法的执行线程是由 Action 的 threadMode 决定的, 也就是说和 Action 在同一个线程
- Log.e("TAG", "result =" + result.toString());
- }
- });
在任意模块下都可添加拦截
- // 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);
- }
- }
源码地址:
https://github.com/HCDarren/DRouter
来源: http://mp.weixin.qq.com/s/R-Q4ISO-ZVx-E5zqZ71KhQ