EventBus简单封装
前言
以前每个页面与每个页面业务逻辑传递让你不知所措,一个又一个接口回调,让你晕头转向,一个又一个参数让你混乱不堪。EventBus一个耦合度低的让你害怕的框架。
什么是EventBus
EventBus是一个消息总线,以观察者模式实现,用于简化程序的组件,可以轻易切换线程,实现各组件之间的刷新通知,以及参数的传递。EventBus3.0跟之前版本的区别
是介入了annotation @Subscribe,取代了以前约定命名的方式。
EventBus的优点
它代替了广播,startActivityforResult,Handle,异步回调等,来实现各个组件间,线程间的通讯,优点是开销小,代码更优雅,以及将发送者与接受者解耦。
EventBus封装
我们今天直接看EventBus封装过程。
EventBus的订阅,接收,发送,我们都放在基类BaseActivity/BaseFragment中完成(EventBus.getDefault().register(this)
订阅事件,发起通信的逻辑直接调用EventBus.getDefault().post(Object event)
来发布事件)。
EventBus封装实战
在Gradle中添加EventBus
依赖:
compile 'org.greenrobot:eventbus:3.0.0'
封装一下EventBus
的订阅、取消订阅、发布等方法:
public class EventBusUtil { public static void register(Object subscriber) {
EventBus.getDefault().register(subscriber);
} public static void unregister(Object subscriber) {
EventBus.getDefault().unregister(subscriber);
} public static void sendEvent(Event event) {
EventBus.getDefault().post(event);
} public static void sendStickyEvent(Event event) {
EventBus.getDefault().postSticky(event);
} // 其他
}
在BaseActivity/BaseFragment
中的onCreate
和onDestroy
方法中订阅和取消订阅,这里添加了一个isRegisterEventBus()
方法,默认返回false
,即不订阅EventBus
,子类Activity/Fragment
如果需要订阅的话复写这个方法并返回true
即可。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (isRegisterEventBus()) {
EventBusUtil.register(this);
}
} /**
* 是否注册事件分发
*
* @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true.
*/
protected boolean isRegisterEventBus() {
return false;
} @Override
public void onDestroy() {
super.onDestroy();
if (isRegisterEventBus()) {
EventBusUtil.unregister(this);
}
}
定义事件Event
:
public class Event<T> {
private int code;
private T data; public Event(int code) {
this.code = code;
} public Event(int code, T data) {
this.code = code;
this.data = data;
} public int getCode() {
return code;
} public void setCode(int code) {
this.code = code;
} public T getData() {
return data;
} public void setData(T data) {
this.data = data;
}
}
通过泛型<T>
指定事件通信过程中的数据类型,code
为事件码,使用的时候给不同的事件类型指定不同的code
。
在BaseActivity\BaseFragment
中添加接收到EventBus
的方法:
/**
* 是否注册事件分发
*
* @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true.
*/
protected boolean isRegisterEventBus() {
return false;
} @Subscribe(threadMode = ThreadMode.MAIN)
public void onEventBusCome(Event event) {
if (event != null) {
receiveEvent(event);
}
} @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onStickyEventBusCome(Event event) {
if (event != null) {
receiveStickyEvent(event);
}
} /**
* 接收到分发到事件
*
* @param event 事件
*/
protected void receiveEvent(Event event) { } /**
* 接受到分发的粘性事件
*
* @param event 粘性事件
*/
protected void receiveStickyEvent(Event event) { }
根据自己项目的需求,在订阅了EventBus
的Activity/Fragment
中复写receiveEvent(Event event)
或receiveStickyEvent(Event event)
来处理接收到事件后的逻辑。
这里也可以不用在BaseActivty/BaseFragment
中添加接受事件的方法(因为添加了过后不能确定的子类的Event
泛型)。那么就直接在订阅的Activity/Fragment
中给接收事件的方法添加EventBus
对应的事件接受注解,并指定参数Event的泛型。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventReceived(Event<User> event) {
if (event != null && event.getCode() == C.EventCode.C) {
User user = event.getData();
}
}
在给定Event
的code
的时候最好在常量池中定义一个类专门用来定义不同类型的EventBus
的code
,这样在接收到EventBus
的地方可以根据这些code
值来判断Event
的来源。
public final class C {
// EventBus Code
public static final class EventCode {
public static final int A = 0x111111;
public static final int B = 0x222222;
public static final int C = 0x333333;
public static final int D = 0x444444;
// other more
}
}
使用示例:
在MainActivity
中复写isRegisterEventBus()
并返回true
注册EventBus
,复写receiveEvent(Event event)
接收发布的事件。
@Override
protected boolean isRegisterEventBus() {
return true;
} @Override
protected void receiveEvent(Event event) {
// 接受到Event后的相关逻辑
switch (event.getCode()) {
case C.EventCode.A:
Log.d("EventBus", "接收到A类型的Event");
break;
case C.EventCode.B:
Log.d("EventBus", "接收到B类型的Event");
break;
case C.EventCode.C:
Log.d("EventBus", "接收到B类型的Event,携带User");
User user = (User) event.getData();
break;
case C.EventCode.D:
Log.d("EventBus", "接收到D类型的Event,携带News");
News news = (News) event.getData();
break;
}
}
在receiveEvent(Event event)
根据对应的事件的code
,判断通信的数据来源和传递的数据类型,以完成对应的逻辑。
在InfoActivity
中发送事件,InfoActivity
只发送不需要接收Event
的话就不注册,也不用复写isRegisterEventBus()
和receiveEvent(Event event)
方法了。
public void sendEventA(View view) {
EventBusUtil.sendEvent(new Event(C.EventCode.A));
} public void sendEventB(View view) {
EventBusUtil.sendEvent(new Event(C.EventCode.B));
} public void sendEventC(View view) {
Event<User> event = new Event<>(C.EventCode.C, new User());
EventBusUtil.sendEvent(event);
} public void sendEventD(View view) {
Event<News> event = new Event<>(C.EventCode.D, new News());
EventBusUtil.sendEvent(event);
}
通过上面的方式,将EventBus
封装到BaseActivity/BaseFragment
中,使得EventBus和项目解耦更加彻底,同时在需要使用的子Activity/Fragment中只需要复写isRegisterEventBus()
和receiveEvent(Event event)
即可,不用每个地方都去订阅和取消订阅。并且给Event
给定code
和泛型能够很好的区分不同的事件来源和数据类型。
EventBus简单封装的更多相关文章
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- FMDB简单封装和使用
工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...
- Android--Retrofit+RxJava的简单封装(三)
1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...
- okhttp3 get post 简单封装
最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...
- python网页请求urllib2模块简单封装代码
这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...
- 对pymysql的简单封装
#coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...
- iOS开发——UI篇OC篇&UITableView简单封装
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
- iOS sqlite 增删改查 简单封装(基于 FMDB)
/** * 对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * * 基于 FMDB * * 操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整 ...
- ADO简单封装(MFC)
简单封装了一下,不是很严谨. /************************************************************************/ /* INSTRUC ...
随机推荐
- 因样式冲突引起的div消失问题
工作需要,搭建一个网站的模型,简单分成三个部分,标题栏,导航栏,主界面,效果如图: 但是点击界面的任意地方,中间的div块消失了,如图所示: 调试,发现在点击界面其他地方的时候display属性有变化 ...
- Mysql一些常用语句
1.查询表创建的时间: SELECT CREATE_TIME FROM INFORMATION_SCHEMA.TABLES WHERETABLE_NAME='TableName'
- JavaEE编程实验 实验1 Java常用工具类编程(未完成)
1.使用String类分割split将字符串“Solutions to selected exercises can be found in the electronic document The T ...
- python中enumerate内置库的使用
使用enumerate,可以自动进行索引下标的赋值,本例代码中使用enumerate,进行excel单元格的赋值操作. 代码如果重复被调用,可将该代码封装成类进行使用 1 import openpyx ...
- [原][粒子特效][spark]发射器emitter
深入浅出spark粒子特效连接:https://www.cnblogs.com/lyggqm/p/9956344.html group添加emitter的方式: eimtter: 上图是spark源码 ...
- leecode第二十六题(删除排序数组中的重复项)
class Solution { public: int removeDuplicates(vector<int>& nums) { int len=nums.size(); ) ...
- 离线人脸识别C#类库分享 虹软2.0版本
目前只封装了人脸检测部分的类库,供大家交流学习,肯定有问题,希望大家在阅读使用的时候及时反馈,谢谢!使用虹软技术开发完成 戳这里下载SDKgithub:https://github.com/dayAn ...
- 学习笔记5—Python 将多维数据转为一维数组 (总结)
<code class="language-python">import operator from functools import reduce a = [[1,2 ...
- 使用http://start.spring.io/ 生成工程
今天学习spring-cloud,无意中发现一个spring提供的构建工程的页面,想记录下,发现有个博客写的很好就直接抄过来了. 原文链接: https://blog.csdn.net/u01050 ...
- legend2---开发日志7(vue的使用场景有哪些,或者说使用的优缺点)
legend2---开发日志7(vue的使用场景有哪些,或者说使用的优缺点) 一.总结 一句话总结:任何页面都可以使用vue,尤其是有交互的或者用ajax的,但是vue插件及其它各种插件加载需要时间, ...