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中的onCreateonDestroy方法中订阅和取消订阅,这里添加了一个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) {

}

根据自己项目的需求,在订阅了EventBusActivity/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();
    }
}

在给定Eventcode的时候最好在常量池中定义一个类专门用来定义不同类型的EventBuscode,这样在接收到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和泛型能够很好的区分不同的事件来源和数据类型。

时间: 2024-10-17 03:08:28

EventBus简单封装的相关文章

JDBC简单封装

/** * JDBC简单封装 * 需要借助FastJsonUtil可以参考上一篇 * @author huangxincheng * */ public class BaseDao { private static String URL; private static String USERNAME; private static String PASSWORD; private static String DRIVER; private  Connection connection; priv

对系统网络请求进行简单封装

AGConnectionNet对系统网络请求进行简单封装,可便利的进行网络请求,并将数据解析与网络请求封装在同一方法下,使用更加便利(JSON 解析采用自身解析方法, XML 解析采用第三方 ReadXML 进行解析). 方法具体参数说明 初始化方法:/*** 类方法,实例化当前数据请求对象 (单例)** @return 当前请求对象*/+ (instancetype)shareRequestData; 仅进行请求数据方法/*** 请求数据 (session 请求)** @param URLSt

iOS sqlite 增删改查 简单封装(基于 FMDB)

/** *  对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * *  基于 FMDB * *  操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整体进行操作 * *  根据 model 对象自动建表,字段类型只支持 NSString , NSIteger , float * *  用到 runtime 运行时获取 model 属性 * */ 1 // 2 // AGDatabaseManager.h 3 // 4 // Created by

简单封装sqlite3 实现实体对象与关系型数据库的相关操作【IOS】

源码如下,只有一个类文件 // //  DBHelper.h // //  Created by Jason_Msbaby on 15/10/15. //  Copyright ? 2015年 张杰. All rights reserved. // /**  *  简单封装了对于sqlite的使用 没有加入对事务及其他复杂的特性     基于传入sql语句的方式进行执行     使用单例模式     根据model对象自动创建表 只支持 NSInter NSString float 数据类型的支

httpclient4.3简单封装

对httpclient4.3版本的一个简单封装,下面是代码 /**  * httputil工具类  *   * @author rex  */ public class HttpUtil {     private static CloseableHttpClient client;     private static BasicCookieStore cookieStore;     private static HttpGet get;     private static HttpPos

MySQL的C++简单封装

/* *介绍:MySQL的简单封装,支持流操作输入输出MySQL语句,然而并没有什么软用,大二学生自娱自乐,有不足求指点 *作者:MrEO *日期:2016.3.26 */ 头文件 my_sql.h 1 #ifndef MY_SQL_H 2 #define MY_SQL_H 3 4 #include <mysql.h> 5 #include <iostream> 6 #include <string> 7 #include <iomanip> 8 9 cla

Android ToolBar 的简单封装

使用过 ToolBar 的朋友肯定对其使用方法不陌生,因为其用法很简单,如果对 ActionBar 使用比较熟练的人来说,ToolBar 就更容易了!不过,相信大家在使用的过程中都遇到过这样一个问题,需要在每一个我们要使用的 xml 中添加 ToolBar 这个控件,比如我需要在 MainActivity中使用 ToolBar,则他的 xml 文件需要这样写, <RelativeLayout xmlns:android="http://schemas.android.com/apk/res

简单封装MessageBox提示对话框

namespace DMS.Common { public class MsgHelper { public static DialogResult ShowErrorMsgBox(string error) { return MessageBox.Show(error, "错误", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } public static DialogResult ShowInformationMsgBox(str

解析xml几个方法的简单封装

import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; /** * * @author D_xiao * */ public class AnalysisXmlByDom { /** * 功能 :通过dom的方法解析