EventBus使用详解

       前言:EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过 EventBus 实现。

一、概述

        首先,复述一下订阅发布模式。订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。

       EventBus是一款针对Android优化的发布/订阅事件总线,基于EventBus可以更加便捷地运用订阅发布模式。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。

       原先使用Intent,Handler,BroadCast时,发送和接收必须在相应的组件间进行处理,而使用EventBus后,发送只需post一下,然后定义一个方法去接收即可,其它的事情一概不管,大大地降低了代码间的耦合系数,便于大型项目的开发。

二、使用方法

<span style="font-size:12px;">// 在Activity中注册与反注册
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this); // 注册
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this); // 反注册
    }

// 在任意地方新建一个事件类
    public class EventBusMsg {}

// 在任意地方调用发送事件
    EventBus.getDefault().post(new EventBusMsg());

// 在注册了的Activity中处理事件(3.0前使用特定名称方法,3.0后使用@Subscribe注解,具体下面会详解)
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusMsg(EventBusMsg eventBusMsg) {}</span>

三、实战

下面代码所实现的效果是这样的:


1.将EventBus的jar包拷贝到/app/libs目录下,并在bulid.gradle下添加依赖(没有jar包的点击这里下载3.0.1版本):

dependencies {
    ......
    compile files('libs/eventbus-3.0.1.jar')
}

2.修改MainActivity布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.eventbus.MainActivity">

    <Button
        android:id="@+id/id_btn_goto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="进入SecondActivity"
        android:textAllCaps="false"/>

    <TextView
        android:id="@+id/id_tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="此处显示SecondActivity发送过来的消息"/>
</LinearLayout>

MainActivity布局中有一个Butoon和TextView,Button用来进入SecondActivity,TextView用来显示SecondActivity发过来的消息。

3.新建一个布局,并改成如下代码,这是SecondActivity的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/id_btn_post"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="向MainActivity发送消息"
        android:textAllCaps="false"/>

</LinearLayout>

SecondActivity布局中只有一个Button,该Butoon用来给MainActivity发送消息。

4.新建一个事件类EventBusMsg,该类就是EventBus传递的类型:

public class EventBusMsg {

    private String mMsg;

    public EventBusMsg(String msg) {
        mMsg = msg;
    }

    public String getMsg() {
        return mMsg;
    }
}

该类通过构造函数放置字符串消息,通过getMsg()获取消息。

5.新建一个SecondActivity,代码如下:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        findViewById(R.id.id_btn_post).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 发布者发布消息
                EventBus.getDefault().post(new EventBusMsg("SecondActivity向您问好!"));
            }
        });
    }
}

该Activity加载了布局并给Button设置了监听器,在监听器中通过EventBus.getDefault().post()发送消息。

6.修改MainActivity代码如下:

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册EventBus
        EventBus.getDefault().register(this);

        textView = (TextView) findViewById(R.id.id_tv);

        findViewById(R.id.id_btn_goto).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this); // 解除EventBus注册
    }

    /** EventBus 3.0版本后使用@Subscribe注解的方式表明该方法为订阅者处理函数
     *  threadMode有四种可选值:ThreadMode.MAIN => 在UI线程执行
     *                          ThreadMode.BACKGROUND => 在后台线程执行
     *                          ThreadMode.ASYNC => 创建新的子线程执行
     *                          ThreadMode.POSTING => 在发送线程执行
     *  该订阅者接收哪种EventBus.post主要取决于订阅函数内的参数匹配 */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusMsg(EventBusMsg eventBusMsg) {
        String msg = eventBusMsg.getMsg();
        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
        textView.setText(msg);
    }
}

该Activity加载了布局并给Button设置了监听器,监听器中通过Intent意图进入SecondActivity。

接下来就是EventBus的使用了:

①在onCreate()中通过EventBus.getDefault().register(this)注册EventBus

②在onDestroy()中通过EventBus.getDefault().unregister(this)反注册EventBus

③创建了onEventBusMsg()方法,通过该方法接收消息并在TextView上显示出来

这里有两点是需要注意的:

⑴EventBus3.0后的版本通过@Subscribe(threadMode = ThreadMode.XXXX)注解该方法为EventBus接收方法。

    ThreadMode有四种可选值:MAIN、BACKGROUD、ASYNC、POSTING。

    ThreadMode.MAIN表示在UI线程执行,3.0之前使用onEventMainThread方法

    ThreadMode.BACKGROUND表示在后台线程执行,3.0之前使用onEventBackground方法

    ThreadMode.ASYNC创建一个新的线程执行,3.0之前使用onEventAsync方法

    ThreadMode.POSTING表示在发送线程执行,3.0之前使用onEvent方法
⑵如果一个项目中有多种Event,接收方法接收哪种Event取决于方法中的参数类型。

   这个理解的时候可以类比广播broadcast,broadcast是通过action进行filter,而EventBus是通过方法中的参数进行filter。

   比如上面的例子就是通过onEventBusMsg()方法中的参数EventBusMsg进行过滤,如果该参数与EventBus.getDefault().post()中的参数不匹配则无法接收相应消息。


源代码下载请点击这里














       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值