




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android路由实现一张图来体会一下路由的作用, 因为我本地没有UML工具, 新的还在下载中 900M+, 我这网速有点受不了. 所以我选择KolourPaint手动绘制一张具有魔性的图片先来体会一下.自己实现一个路由的动机那到了我们Android开发中呢? 如果我们把项目模块化了, 那两个组件间进行通讯或者跳转, 我们一般构建Intent的方式就不再使用了, 很简单, 因为在模块A中根本找不到模块B中的C类, 这就需要我们自定义路由规则, 绕一道弯去进行跳转, 说白了就是给你的类起一个别名, 我们用别用去引用. 其实在我准备自己去实现一个路由的时候我是google了一些解决方案的, 这些方案大致可分为两种.完全自己实现路由, 完全封装跳转参数利用隐式意图跳转对于这两种方式我总结了一下, 个人认为第一种方式封装的太多, 甚至有些框架是RESTFul like的, 这样的封装一是学习成本太高, 二是旧项目改动起来太麻烦. 那第二种方式呢? 利用隐式意图是一种不错的选择, 而且Android原生支持, 这也是大家在尝试模块化开发时的一个选择, 不过这种方式仅支持Activity, Service, BroadcastReceiver, 扩展性太差. 综上因素, 我还是决定自己实现一个路由, 参考自上面的局限性, 我们的路由具有一下2个特点.上手简单, 目标是与原生方式一行代码之差就能实现Activity, Service, BroadcastReceiver调用.扩展性强, 开发者可以任意添加自己的路由实现, 不仅仅局限于Activity, Service, BroadcastReceiver.体验一下在了解具体实现代码之前, 我们先来了解一下新的路由怎么使用, 使用起来是不是符合上面两点, 首先我们先建立三个moduler, 分别是壳app, 商城模块shoplib, bbs模块bbslib. app模块就是我们的壳了, 我们需要利用app模块去打包, 而且app也是依赖shoplib和bbslib的, 所以我们可以在app的application里进行路由的注册.public class App extends Application Override public void onCreate() super.onCreate(); setupRouter(); private void setupRouter() Router.router(ActivityRule.ACTIVITY_SCHEME + shop.main, ShopActivity.class); Router.router(ActivityRule.ACTIVITY_SCHEME + bbs.main, BBSActivity.class); 这里注册了两个路由, 分别是商城模块的的ShopActivity和bbs模块的BBSActivity, 它们都是通过Router类的静态方法router方法进行注册的, 两个参数, 第一个参数是路由地址(也可以理解成别名), 第二个参数对应的类. 注册完了, 那接下来就是如何使用了, 我们来看看在商城模块如何跳转BBS模块吧.public class ShopActivity extends AppCompatActivity Override protected void onCreate(Nullable Bundle savedInstanceState) super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setTextSize(50); tv.setText(SHOP!); setContentView(tv); tv.setOnClickListener(new View.OnClickListener() Override public void onClick(View v) Intent it = Router.invoke(ShopActivity.this, ActivityRule.ACTIVITY_SCHEME + bbs.main); startActivity(it); ); 主要代码是在click事件里, 我们调用了Router.invoke方法, 第一个参数是当前Activity, 第二个参数就是我们前面注册的路由了, 这里都很好理解, 关键是看它的返回值, 这里直接返回了一个Intent, 这一点是最棒的 返回Intent也就是说明下面的代码和我们使用原生方式没有任何区别! 这一点符合上面我们说到的上手简单的目的.至于第二点目标, 高扩展性, 大家可以实现Rule接口自定义路由Rule, 然后调用Router.addRule(String scheme, Rule rule)方法进行路由规则的注册. Rule接口的定义如下,/* * 路由规则接口 * Created by qibin on 2016/10/8. */public interface Rule /* * 添加路由 * param pattern 路由uri * param klass 路由class */ void router(String pattern, Class klass); /* * 路由调用 * param ctx Context * param pattern 路由uri * return code V 返回对应的返回值 */ V invoke(Context ctx, String pattern);解释一下, 首先是Rule接口的两个范型, 第一个T是我们注册的路由类型, 例如前面使用的Activity类型, 第二个V是invoke方法的返回值类型, 例如前面使用的Intent类型.至于自定义的代码, 这里我赖了, 没有提供demo 大家可以尝试自定义一下.路由实现代码接下来我们开始进入实现代码环节 在来是代码之前, 还是先来一张图了解下这个Router的结构.带着上面的图片, 我们来看代码, 首先我们来看看Router类, 毕竟我们在使用的时候都是在和Router打交道./* * Usage: * * step 1. 调用Router.router方法添加路由 * step 2. 调用Router.invoke方法根据pattern调用路由 * * Created by qibin on 2016/10/9. */public class Router /* * 添加自定义路由规则 * param scheme 路由scheme * param rule 路由规则 * return code RouterInternal Router真实调用类 */ public static RouterInternal addRule(String scheme, Rule rule) RouterInternal router = RouterInternal.get(); router.addRule(scheme, rule); return router; /* * 添加路由 * param pattern 路由uri * param klass 路由class * return code RouterInternal Router真实调用类 */ public static RouterInternal router(String pattern, Class klass) return RouterInternal.get().router(pattern, klass); /* * 路由调用 * param ctx Context * param pattern 路由uri * return code V 返回对应的返回值 */ public static V invoke(Context ctx, String pattern) return RouterInternal.get().invoke(ctx, pattern); 哈, Router的代码很简单, 主要就是起到一个类似静态代理的作用, 主要的代码还是在RouterInternal里, 那来看看RouterInternal的结构吧.public class RouterInternal private static RouterInternal sInstance; /* scheme-路由规则 */ private HashMap mRules; private RouterInternal() mRules = new HashMap(); initDefaultRouter(); /* * 添加默认的Activity,Service,Receiver路由 */ private void initDefaultRouter() addRule(ActivityRule.ACTIVITY_SCHEME, new ActivityRule(); addRule(ServiceRule.SERVICE_SCHEME, new ServiceRule(); addRule(ReceiverRule.RECEIVER_SCHEME, new ReceiverRule(); /*package */ static RouterInternal get() if (sInstance = null) synchronized (RouterInternal.class) if (sInstance = null) sInstance = new RouterInternal(); return sInstance; 首先RouterInternal是一个单例, 一个mRules变量用来保存我们的路由规则, 在构造中我们注册了三个默认的路由规则, 这三个路由规则想都不用想就知道是Activity, Service和BroadcastReceiver的. 接下来看看其他的方法./* * 添加自定义路由规则 * param scheme 路由scheme * param rule 路由规则 * return code RouterInternal Router真实调用类 */public final RouterInternal addRule(String scheme, Rule rule) mRules.put(scheme, rule); return this;addRule方法是添加路由规则的实现, 这里我们是直接向mRules这个HashMap中添加的.private Rule getRule(String pattern) HashMap rules = mRules; Set keySet = rules.keySet(); Rule rule = null; for (String scheme : keySet) if (pattern.startsWith(scheme) rule = rules.get(scheme); break; return rule;getRule的作用是根据pattern来获取规则, 这是一个私有的方法, 所以在使用的时候不需要关心, 它的原理很简单, 就是根据你的pattern来匹配 scheme来获取对应的Rule./* * 添加路由 * param pattern 路由uri * param klass 路由class * return code RouterInternal Router真实调用类 */public final RouterInternal router(String pattern, Class klass) Rule rule = getRule(tern); if (rule = null) throw new NotRouteException(unknown, pattern); rule.router(pattern, klass); return this;这个router方法就是我们添加路由的实现了, 首先我们根据路由的uri来获取对应的Rule, 然后调用该Rule的 router方法, 至于Rule.router方法如何实现的, 我们稍后看/* * 路由调用 * param ctx Context * param pattern 路由uri * return code V 返回对应的返回值 */*package*/ final V invoke(Context ctx, String pattern) Rule rule = getRule(pattern); if (rule = null) throw new NotRouteException(unknown, pattern); return rule.invoke(ctx, pattern);invoke方法就是我们调用的时候执行的代码的, 返回值T是返回的Rule范型中指定的类型, 例如前面的Intent. 综上代码, 我们发现RouterInternal其实就是一个管理Rule的类, 具体的调用还是在各个Rule中实现, 上面提到过, Rule是一个接口, 它具有两个范型, 分别对应的调用 invoke的返回值类型和我们要路由的类的类型. 解析来我们就来看看默认的几个路由规则是如何实现的.对于Activity, Service, BroadcastReceiver的调用, 总结了一下, 它们其实都是返回的Intent类型, 所以我们可以先构建一个指定返回值是Intent的Base类型./* * 返回Intent的路由规则的基类 * Created by qibin on 2016/10/9. */public abstract class BaseIntentRule implements Rule private HashMapString, Class mIntentRules; public BaseIntentRule() mIntentRules = new HashMap(); /* * inheritDoc */ Override public void router(String pattern, Class klass) mIntentRules.put(pattern, klass); /* * inheritDoc */ Override public Intent invoke(Context ctx, String pattern) Class klass = mIntentRules.get(pattern); if (klass = null) throwException(pattern); return new Intent(ctx, klass); /* * 当找不到路由规则时抛出异常 * param pattern 路由pattern */ public abstract void throwException(String pattern);router方法不多说, 还
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年海阳市消防员考试笔试试题(含答案)
- 农产品社区电商平台创新创业项目商业计划书
- 虚拟旅行纪念品DIY与定制创新创业项目商业计划书
- 网络安全解决方案集成服务创新创业项目商业计划书
- 橡胶管道系统节能改造方案创新创业项目商业计划书
- 汽车线下区域市场推广策划创新创业项目商业计划书
- 现场服务管理(FSM)创新创业项目商业计划书
- 现场急救知识培训
- 2025年学前教育信息化与家庭教育融合应用报告
- 2025年教育信息化2.0时代下教师教育信息化应用场景研究报告
- 2025年电气系统故障排查与维修技能考核试卷及答案(全新)
- 模拟联合国社团课件
- 2025-2026学年统编版(2024)小学语文二年级上册教学计划及进度表
- 2025湖南湘潭湘乡市融媒体中心招聘事业单位工作人员10人笔试备考题库及答案解析
- 县级医院骨科发展路径规划
- 健康管理师二级《理论知识》模拟考试试卷附答案
- 第六章 人体生命活动的调节 大单元教学设计 人教版(2024)生物八年级上册
- 2025湖南省全日制用工劳动合同书
- 2025广西公需科目真题续集(附答案)
- (正式版)SH∕T 3548-2024 石油化工涂料防腐蚀工程施工及验收规范
- 中小学教师违反职业道德行为处理办法
评论
0/150
提交评论