我们知道Android的组件化离不开Router,路由的主要主要作用是:消息的中转站,为我们的项目多模块的依赖解耦。,当然市面上有三方路由框架,比如阿里的ARouter就是一个不错的选择,但我们还是要自己自定义一个Router,来研究一下,毕竟自己动手丰衣足食嘛,ok,我们进入正题。

项目分析

这是我demo的项目结构:

image.png

当然凡是用到路由的项目,其依赖关系一定复杂,但我们这里只是为了讲解路由的实现,所以就项目的耦合度并不高。

主要是app,fifferentprocess,sameprocessmodule这三个模块的依赖,通过自定义router实现解耦,common模块就是依赖模块常用的一些静态变量统一存放,便于管理。

router模块的主要代码分析

我们说了router主要作用是消息的中转站,所以我们先看一下其内部的构成类:

image.png

没错就是这五个类,其中的MainActivity里啥也没有,也就是Xaction,Xrouter,XrouterRequest,XrouterResponse这四个类,是不是很简单,那我们就来逐一分析一下。

Xrouter

Xrouter是router模块的消息中转类,专门处理消息。我们看其代码:

private static final String TAG = "Xrouter";

//使用volatile关键字的好处是保证线程可见

public static volatile Xrouter mXrouter ;

//使用HashMap初始化一个队列mXactions,用来存储不同种类的消息通道

public static HashMap mXactions ;

private Xrouter() {

mXactions =new HashMap<>();

}

//单例模式,支持多线程。参考:https://www.jianshu.com/p/769f2593c94e

public static Xrouter getInstance(){

if(mXrouter == null){

synchronized (Xrouter.class){

if(mXrouter == null){

mXrouter =new Xrouter();

}

}

}

return mXrouter;

}

//往消息队列插入不同消息通道的方法,这里参数包括通道名称和通道本身Xaction.java

public void registerAction(String actionKey,Xaction xaction){

if(mXactions.containsKey(actionKey)){

Log.e(TAG, "该通道已经注册");

}else{

mXactions.put(actionKey,xaction);

}

}

//对应通道发送消息的方法

public XrouterResponse senMessage(Context context ,XrouterRequest xrouterRequest){

XrouterResponse mXrouterResponse=new XrouterResponse();

Xaction mXaction =getmXAction(xrouterRequest.getActionName());

//Xaction对象不为空,说明该通道存在,之前已经注册,可以正常发送消息

if(mXaction != null){

//将发送的消息内容(xrouterRequest.getData())传递给对应的Xaction的实现类

Object mObject =mXaction.startAction(context,xrouterRequest.getData());

mXrouterResponse.setResponseResult(XrouterResponse.RESPONSE_SUCCESS_CODE,XrouterResponse.RESPONSE_SUCCESS,mObject);

}else{

mXrouterResponse.setResponseResult(XrouterResponse.RESPONSE_FAIL_CODE,XrouterResponse.RESPONSE_FAIL,"该Xaction没有创建");

}

return mXrouterResponse;

}

//返回消息通道对应的对象

public Xaction getmXAction(String actionName){

if(mXactions.containsKey(actionName)){

return mXactions.get(actionName);

}

return null;

}

注释都很详细,主要是三个方法registerAction(),senMessage()和 getmXAction()方法,既然是消息的中转站那么就要存储消息,我们这里用HashMap的一个HashMap来存消息Xaction.

分别来说一下这三个方法

registerAction()

我们在用HashMap存消息之前先要注册消息对象,而registerAction方法通过key,value的形式把我们的Xaction放入HashMap存储起来,完成注册。

senMessage()

这个方法比较重要,简单来说就是我们发消息给相关的module.,里面涉及的XrouterResponse,Xaction,Xrespinse我们稍后说。

getmXAction()

此方法就是查找我们之前在HashMap中注册的消息即Xaction是否已经存在,存在就返回其对象。

Xaction

image.png

Xaction是抽象类,里面包含一个抽象方法startAciont,此抽象方法主要是让实现类对发送消息做做一个传递,也就是将发送的消息传递给对应的module,并返回结果(是否成功将消息传递)。

XrouterRequest

public class XrouterRequest {

//消息通道名称

private String mActionName;

//消息通道携带的数据

private HashMap mData;

private XrouterRequest(){

mData =new HashMap<>();

}

public static XrouterRequest create(){

return new XrouterRequest();

}

public XrouterRequest putData(String key, Object value){

mData.put(key,value);

return this;

}

public XrouterRequest putActionName(String actionName){

mActionName=actionName;

return this;

}

public String getActionName(){

return this.mActionName;

}

public HashMap getData(){

return this.mData;

}

}

发送消息的载体,也就是具体消息也携带的内容,包括两个变量一个是mActionName,此mActionName和注册到HashMap中的Xaction的key对应,便于查找到Xaction对象,而其中的mData这是携带传递的内容。

XrouterResponse

public class XrouterResponse {

public static final String RESPONSE_SUCCESS="发送消息成功";

public static final String RESPONSE_FAIL="发送消息失败";

public static final int RESPONSE_SUCCESS_CODE=1;

public static final int RESPONSE_FAIL_CODE=0;

//状态码

private int mcode;

//描述:消息发送成功或失败

private String mdes;

//消息反馈的其他信息

private Object mbody;

//获取响应消息

public JSONObject getResponseResult(){

JSONObject mJSONObject=null;

try {

mJSONObject =new JSONObject();

mJSONObject.put("code",mcode).put("des",mdes).put("content",mbody);

} catch (JSONException e) {

e.printStackTrace();

}

return mJSONObject;

}

//设置响应消息

public void setResponseResult(int code ,String des,Object obj){

this.mcode=code;

this.mdes=des;

this.mbody=obj;

}

}

消息的发送结果的响应类,主要由状态码,描述和其他反馈信息三部分构成。包含一个获取消息结果一个设置消息结果的方法,没啥好说的。

differentprocess和sameprocess模块

从字面意思来看他们一个是和app在一个进程中,一个不再一个进程中。这里主要是为了测试如果不在同一个进程中路由的效果,不再进程中主要是因为我在differentprocess模块的功能清单文件中添加了:

image.png

这两个模块(differentprocess和sameprocess)都实现了Xaction的抽象通道方法startAction,j具体如下:

image.png

这样就可以将消息通过通道传递给相应的activity了。而在activity中,我们只是对传递的内容进行了展示,如下:

image.png

common模块

没事说的,就是几个常量,自己下载demo看。

app模块

该模块中两个类

-MainActivity中

public class MainActivity extends AppCompatActivity {

Button btn_sameProcess;

Button btn_differentProcess;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn_sameProcess=findViewById(R.id.sameprocess);

btn_differentProcess=findViewById(R.id.differnetprocess);

btn_differentProcess.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//封装传递的请求数据到XrouterRequest

XrouterRequest mXrouterRequest =XrouterRequest.create().putData("data","发给不同进程的数据测试").putActionName(DifferentProcessActionMessage.DIFFERENTPROCESSACTIONNAME);

XrouterResponse mXrouterResponse=Xrouter.getInstance().senMessage(MainActivity.this,mXrouterRequest);

Toast.makeText(MainActivity.this,mXrouterResponse.getResponseResult()+"",Toast.LENGTH_LONG).show();

}

});

btn_sameProcess.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//封装传递的请求数据到XrouterRequest

XrouterRequest mXrouterRequest =XrouterRequest.create().putData("data","发给同进程的数据测试").putActionName(SameProcessActionMessage.SANEPORICESSBANE);

XrouterResponse mXrouterResponse=Xrouter.getInstance().senMessage(MainActivity.this,mXrouterRequest);

Toast.makeText(MainActivity.this,mXrouterResponse.getResponseResult()+"",Toast.LENGTH_LONG).show();

}

});

}}

MainActivty就是两个按钮一个是跳转到同进程一个跳转到不同进程的module中,将携带的信息存放到XrouterRequest中,同时返回响应对象XrouterResponse,简单toast了一下。

BaseApplication

Xaction消息的注册建议存放点Application中,如下:

public class BaseApplication extends Application {

@Override

public void onCreate() {

super.onCreate();

//通道的初始化最好放在Application中

initAction();

}

private void initAction() {

Xrouter.getInstance().registerAction(DifferentProcessActionMessage.DIFFERENTPROCESSACTIONNAME,new com.hxzk.bj.differnertprocess.action.DifferentProcessAction());

Xrouter.getInstance().registerAction(SameProcessActionMessage.SANEPORICESSBANE,new com.hxzk.bj.sameprocessmodule.action.SameProcessAction());

}

}

就这么多,建议大家下载demo具体查看,以上传github:点我传送

告辞!

android自定义队列,Android-自定义Router(路由)相关推荐

  1. android+动画队列,Android属性动画详解

    前言 属性动画是Android 3.0(API 11)新加入的动画框架,属性动画弥补了视图动画的很多短板,因此已经成为大多数动画场景的首选框架. 目录 目录 1. 属性动画出现的原因 在属性动画出现以 ...

  2. android自定义队列,Android 消息机制(一)消息队列的创建与循环的开始 Looper与MessageQueue...

    写在前面 本文基于Android 7.1.1 (API 25)的源码分析编写 与之前的触摸事件分发机制分析的文章一样,Android系统机制的分析中关键的一环就是事件消息的处理.之前也说过,Andro ...

  3. 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件

    博客地址 : http://blog.csdn.net/shulianghan/article/details/41520569 代码下载 : -- GitHub : https://github.c ...

  4. android炫酷的自定义view,Android自定义View实现炫酷进度条

    本文实例为大家分享了Android实现炫酷进度条的具体代码,供大家参考,具体内容如下 下面我们来实现如下效果: 第一步:创建attrs文件夹,自定义属性: 第二步:自定义View: /** * Cre ...

  5. android单线字体,Android自定义字体

    在main文件夹下,新建assets/fonts文件,添加.otf文件 image.png 字体工具类 import android.app.Application; import android.g ...

  6. android 自定义命名空间,Android自定义ActionBar实例

    本文实例讲述了android自定义actionbar的实现方法.分享给大家供大家参考.具体实现方法如下: android 3.0及以上已经有了actionbar的api,可以通过引入support p ...

  7. android 自定义图片容器,Android应用开发中自定义ViewGroup视图容器的教程

    一.概述在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥?ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性, ...

  8. android sqlite自定义函数,Android中自定义一个View的方法详解

    本文实例讲述了Android中自定义一个View的方法.分享给大家供大家参考,具体如下: Android中自定义View的实现比较简单,无非就是继承父类,然后重载方法,即便如此,在实际编码中难免会遇到 ...

  9. Android Paint应用之自定义View实现进度条控件

    在上一篇文章<Android神笔之Paint>学习了Paint的基本用法,但是具体的应用我们还没有实践过.从标题中可知,本文是带领读者使用Paint,自定义一个进度条控件. 上图就是本文要 ...

最新文章

  1. java mvc 绑定_关于Java:Spring MVC:将请求属性绑定到控制器方法参数
  2. BigData:绘制2018年福布斯中国富豪榜人根据出生地绘制个人或其家族财富分布热点图
  3. [LeetCode]题解(python):072-Edit Distance
  4. 《计算机网络自顶向下》知识体系完全梳理
  5. agv系统介绍_AGV地面控制系统介绍
  6. NLP 《马尔科夫链》
  7. Scala class
  8. 转化率模型之转化数据延迟
  9. concurrent包下线程池类小结
  10. 免费的数据恢复软件 恢复丢失的数据
  11. .net 根据银行卡获取银行信息
  12. PackageManager.getPackageSizeInfo||UserHandle.myUserId()
  13. 机器学习中的特征工程总结
  14. react-spa小demo
  15. /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start‘
  16. 上海电力大学本科毕业论文答辩PPT模板
  17. elementUI兼容ie浏览器问题(笔记)
  18. 2006高端IT技术图书点评(首发《中华读书报》)
  19. 2D轮转图选角色换衣服
  20. 登入联机服务器失败怎么 修复,元气骑士连接服务器失败 连接不上网络怎么办...

热门文章

  1. html统计筛选表格count,Excel表格技巧—统计工作必备的COUNTIF函数的使用方法
  2. 如何在微信收发邮件,邮箱品牌有哪些?
  3. 《微图4.0》新版发布
  4. 不是408,但很像408!双一流东北林业大学计算机考研改考!
  5. Others12_瞳距测量的方法大全
  6. 解决浏览器主页被劫持为hao123
  7. 为什么要用impl继承service层_讨论:Service层需要接口吗?
  8. js事件委托及其原理
  9. 微博动态来自Android,Android新浪微博开发(二)主UI的实现:动态建立TabActivity
  10. 一:ubuntu系统汉化问题