文档章节

本地消息传递EventBus

该如何是好
 该如何是好
发布于 2016/02/29 17:10
字数 1347
阅读 448
收藏 6

EventBus跟github上大神的不一样,是我大致根据自己的需求,然后简单实现的版本,主要满足个人需求。

/**
 * 消息处理者
 * 
 * @author jeff
 *
 */
public interface EventHandler {
 /**
  * 当接收到消息时回调此方法
  * 
  * @param event 发生的事件
  */
 public void onEvent(LocalEvent event);
}

这个接口主要是事件发生的回调接口。

/**
 * 软件消息处理中心
 * 
 * @author jeff
 *
 */
public class EventBus {
 
 private static EventBus instance = new EventBus();
 private List<EventHandler> handlers;
 private Handler uiThreadHandler;
 
 /**
  * 获取消息处理器
  * 
  * @return
  */
 public static EventBus getDefault() {
  
  return instance;
 }
 
 private EventBus() {
  
  uiThreadHandler = new Handler();
  handlers = new ArrayList<EventHandler>();
 }
 
 /**
  * 添加关注本地广播
  * 
  * @param handler
  */
 public void add(EventHandler handler) {
  
  synchronized (this) {
   handlers.add(handler);
  }
 }
 
 /**
  * 移除关注本地广播
  * 
  * @param handler
  */
 public void remove(EventHandler handler) {
  
  synchronized (this) {
   handlers.remove(handler);
  }
 }
 
 /**
  * 同步发送一个消息广播
  * 
  * @param event
  */
 public void post(LocalEvent event) {
  
  synchronized (this) {
   for(EventHandler handler : handlers)
    handler.onEvent(event); 
  }
 }
 
 /**
  * 异步发送一个消息广播
  * 
  * @param event
  */
 public void postInOtherThread(final LocalEvent event) {
  
  uiThreadHandler.post(new Runnable() {
   
   @Override
   public void run() {
    synchronized (this) {
     for(EventHandler handler : handlers)
      handler.onEvent(event); 
    }
   }
  });
 }
 
 /**
  * 异步显示一个toast消息
  * 
  * @param msg
  */
 public void noticeMsg(final String msg) {
  
  uiThreadHandler.post(new Runnable() {
   
   @Override
   public void run() {
    ToastTool.showToast(msg);
   }
  });
 }
 
 /**
  * 异步执行一个任务
  * 
  * @param runnable
  */
 public void runningOnUiThread(Runnable runnable) {
  
  uiThreadHandler.post(runnable);
 }
 
 /**
  * 异步执行一个任务,带有延迟
  * 
  * @param runnable
  */
 public void runningOnUiThread(Runnable runnable, int delay) {
  
  uiThreadHandler.postDelayed(runnable, delay);
 }
}

    EventBus就是整个本地事件处理的核心,用单件模式维护,为了简单直接用最简单的方式创建默认对象,而且还线程安全,如果有需求也可以把这个方式改为懒惰型。我会在application中调用下getDefault()方法保证EventBus在主线程中被初始化,因为我需要创建一个主线程的handler用来异步通信。

    消息通知就是用非常常见的观察者模式,将每个观察者都记录在一个list里面,当然添加,移除和通知这个过程都是同步的确保线程安全。

    消息的通知就有同步跟异步通知两种,因为我的通知大部分工作是通知界面更新,少部分其他的简单工作,所以我并不介意工作都放在主线程中处理,如果有工作量巨大则要考虑事件的接收者收到消息后在子线程处理,或者接口添加在其他线程收消息的接口,EventBus则判断EventHandler需要哪种方式,需要在其他线程的就添加到子线程然后再去通知事件发生。

    最后的几个异步的方法主要是我在其他线程需要直接在主线程处理些东西的时候用的,比如显示一个toast,做些其他限定只能在主线程工作的事。

 /**
 * 本地消息事件
 * 
 * @author jeff
 *
 */
public class LocalEvent {
 public static final int EVENT_TYPE_X = 101;
 public static final int EVENT_TYPE_XX = EVENT_TYPE_X + 1;
  
 private int eventType;
 private Object eventData;
 private String eventMsg;
 private int eventValue;
 public static LocalEvent getEvent(int eventType) {
  
  return getEvent(eventType, -1, "", null);
 }
 public static LocalEvent getEvent(int eventType, String eventMsg) {
  
  return getEvent(eventType, -1, eventMsg, null);
 }
 
 public static LocalEvent getEvent(int eventType, int eventValue) {
  
  return getEvent(eventType, eventValue, "", null);
 }
 public static LocalEvent getEvent(int eventType, int eventValue, String eventMsg) {
  
  return getEvent(eventType, eventValue, eventMsg, null);
 }
 public static LocalEvent getEvent(int eventType, int eventValue, String eventMsg, Object eventData) {
  
  LocalEvent event = new LocalEvent();
  event.eventMsg = eventMsg;
  event.eventType = eventType;
  event.eventData = eventData;
  event.eventValue = eventValue;
  
  return event;
 }
 
 public int getEventType() {
  return eventType;
 }
 public void setEventType(int eventType) {
  this.eventType = eventType;
 }
 public Object getEventData() {
  return eventData;
 }
 public void setEventData(Object eventData) {
  this.eventData = eventData;
 }
 public String getEventMsg() {
  return eventMsg;
 }
 public void setEventMsg(String eventMsg) {
  this.eventMsg = eventMsg;
 }
 public int getEventValue() {
  return eventValue;
 }
 public void setEventValue(int eventValue) {
  this.eventValue = eventValue;
 }
}

        然后就是事件的模型了,主要由一个type,value,msg跟一个Object的data组成,参考handler的msg的数据内容实现,一般这四个参数也能满足大部分需求,如果有其他特殊需求可以再增加数据位。

 

    接下去就是使用流程了,需要关注的fragment或activity在onCreate中EventBus.getDefault().add(this);在onDestory中EventBus.getDefault().remove(this);然后再实现EventHandler接口即可。

    事件发生的地点则通过EventBus.getDefault().post(LocalEvent.getEvent(LocalEvent.EVENT_TYPE_X, value, msg));然后关注了事件的fragment或者activity的onEvent会被回调然后实现通知的效果。

    这样的好处是使用起来非常的方便简单,也更加符合面向对象的思想,事件发生的地点只需要考虑将发生的事件传递出去而不关心谁想知道,EventBus则会将消息恰当的通知所有关心的人。这里的话我将事件类型的匹配没有放在EventBus中进行,因为这样更加简单,毕竟我总的EventHandler不会太多,如果本地通知的消息过多,可以考虑使用map来存储EventHandler,以事件类型为键,这样可以省去很多没用的通知,也可以加速匹配过程,只给EventHandler通知他们关心的事件而不是现在这样拿到了事件再去看看是不是关心,这样做也更像android的广播机制吧。

© 著作权归作者所有

共有 人打赏支持
上一篇: 部署flask2
下一篇: 算法(4).冒泡排序
该如何是好
粉丝 1
博文 9
码字总数 5243
作品 0
闵行
私信 提问
Vue自定义组件事件传递:EventBus部分

前言 组件化应用构建是Vue的特点之一,因此我们在Vue的实际开发过程中会经常需要封装自定义组件,以提高开发的效率。 而组件在大部分情况下并不会孤立的存在,它必然会与父组件和兄弟组件产生...

丨大麦
2018/06/24
0
0
Guava库学习:学习Guava EventBus(一)EventBus

在软件开发过程中,对象信息的分享以及相互直接的协作是必须的,困难在于确保对象之间的沟通是有效完成的,而不是拥有成本高度耦合的组件。当对象对其他组件的责任有太多的细节时,它被认为是...

Realfighter
2014/12/29
0
0
【Android翻译】组件通信模式

目标:避免紧耦合 本文对原文进行了精简 原文链接:Communication patterns for application components 紧耦合 组件之间相互持有引用,以及直接调用方法.在下面的代码中,MenuFragment持有Magaz...

xesam
2015/04/23
0
0
滴-EventBus-新司机考驾照

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27489007/article/details/84989802 EventBus缘起何方 她是由greenrobot组织贡献的一个基于观察者模式的A...

秋隆
2018/12/13
0
0
EventBus的初级使用--Activity间传递消息

Activity 间的数据通信,对于数据量比较大的,避免使用 Intent + Parcelable 的方式,可以考虑 EventBus 等替代方案,以免造成 TransactionTooLargeException。 EventBus是一款Android下的发...

lanyu96
2018/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mac 10.14 编译Android 8.1源码及刷入nexus 6p

环境准备 官网 描述得已经相当清楚了 ,这里稍微总结一下: 创建区分大小写的磁盘映像 mac系统默认是不区分大小写的,所以我们需要创建一个区分大小写的文件系统 hdiutil create -type SPARS...

猴亮屏
12分钟前
0
0
js获取url参数

function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); var url =decodeURI(decodeURI(window.location.search)); var r = url.substr(1).match(reg);//s......

ArlenXu
19分钟前
1
0
(转)Spring MVC的常用注解

@Controller(常用) 注解一个类表示控制器,Spring MVC会自动扫描标注了这个注解的类。 @RequestMapping(常用) 请求路径映射,可以标注类,也可以是方法,可以指定请求类型,默认不指定为...

政旭Arvin
25分钟前
0
0
Navicat使用教程:在Navicat Monitor for MySQL/MariaDB中配置实例

下载Navicat Monitor最新版本 Navicat Monitor 是一套安全、简单而且无代理的远程服务器监控工具。它具有强大的功能使你的监控发挥最大效用。受监控的服务器包括 MySQL、MariaDB 和 Percona ...

电池盒
28分钟前
0
0
sql根据日期查询,本周,本月,本年,今日相关统计

sql根据日期查询,本周,本月,本年,今日相关统计 昨天 select * from tb where datediff(day, 时间字段 ,getdate()) = 1 今天 select * from tb where datediff(day, 时间字段 ,getdate()) = ...

BraveLN
38分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部