EventBus使用详解

来源:互联网 发布:java入门教程视频 编辑:程序博客网 时间:2024/06/07 13:15

       前言: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()中的参数不匹配则无法接收相应消息。


源代码下载请点击这里














       

0 0