EventBus使用

EventBus简单介绍

EventBus就是事件总线的意思,个人理解为:我们先把一个个事件(event)发送到总线上,然后EventBus根据已注册的订阅者(subscribers)来匹配相应的事件,进而把事件传递给订阅者处理(可以指定不同的线程处理)。我们在平时开发的时候,当遇到Activity与Activity或者Activity与Fragment之间的通信,往往采用Intent,又或者线程之间使用Handler进行通信,这样代码难免会复杂许多,而使用EventBus能极大简化两个组件之间的通信问题,而且效率极高,而EventBus升级到3.0版本后,开发者能够自定义订阅方法的名字,而没必要规定以“onEventXX”开头的方法了,这样也自由化了很多,而且支持了粘性事件的分发等,因此学会使用EventBus3.0对我们的开发有极大的好处。

一、eventbus组成

EventBus的主要由三个要素组成,分别如下所示:

(1)Event:事件,可以是任意类型的对象。(组件之间通过传递的对象通信)
(2)Subscriber:事件订阅者,他有四种线程处理模型。而在EventBus3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING),四种线程模型下面会讲到。
(3)Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus的post(Object)方法。可以自己实例化EventBus对象,但一般使用EventBus.getDefault()就好了,根据post函数参数的类型,会自动调用订阅相应类型事件的函数。

接着阐述(2)中所提到的EventBus的四种ThreadMode(线程模型),分别如下所示:
(1)POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
(2)MAIN: 事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
(3)BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
(4)ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。

二、使用步骤

EventBus使用起来很简单,分为六个步骤:

1.添加依赖:
compile ‘org.greenrobot:eventbus:3.0.0’

2.自定义一个事件类

public class MessageEvent {

}
3.在需要订阅事件的地方注册事件
EventBus.getDefault().register(this);

4.发送事件
EventBus.getDefault().post(messageEvent);

5.处理事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {

}

6.取消事件订阅
EventBus.getDefault().unregister(this);

三、使用demo

根据上述的使用步骤一步步进行即可,具体demo如下:
首先给出本demo的布局文件。
fragment_msg.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="820"
        android:textSize="50sp"
        android:gravity="center_horizontal"/>
</LinearLayout>

activity_main.xml

<?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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical"
        android:background="#6f6669">
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/panhouye"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="伐木机" />
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/bikonghai"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="影魔" />
        <Button
            android:layout_gravity="center_horizontal"
            android:id="@+id/postSticky"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="撼地神牛" />
    </LinearLayout>
    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"></FrameLayout>
</LinearLayout>

activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30sp"
        android:gravity="center_horizontal"
        android:id="@+id/tv"
        android:text="no data"/>
</RelativeLayout>

(1)在工程app中的gradle中添加依赖:compile ‘org.greenrobot:eventbus:3.0.0’
(2)创建事件类:MessageEvent。代码如下:

/**
 * Created by firesmog on 2017/3/14.
 */
public class MessageEvent {
    String data;
    public MessageEvent() {
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }

    public MessageEvent(String data) {
        this.data = data;
    }
}

(3)注册事件,这里给出MainActivity

package example.com.myapplication;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button panhouye;
    private Button bikonghai;
    private Button postSticky;
    private MsgFragment msgFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        panhouye= (Button) findViewById(R.id.panhouye);
        bikonghai= (Button) findViewById(R.id.bikonghai);
        postSticky= (Button) findViewById(R.id.postSticky);

        panhouye.setOnClickListener(this);
        bikonghai.setOnClickListener(this);
        postSticky.setOnClickListener(this);
        //添加fragment到右侧的帧布局中
        msgFragment = new MsgFragment();
   //使用fragment替换掉framelayout     getSupportFragmentManager().beginTransaction().add(R.id.framelayout,msgFragment).commit();
    }  
    @Override
    protected void onResume() {
        super.onResume();
        //注册eventbus
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //取消注册
        EventBus.getDefault().unregister(this);
    }
    /**
     * 事件发布者(通过按钮点击事件进行事件发布)
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            //(1)事件发布中所传参数可以作为右侧fragment文本的修改内容
            //(2)事件发布中所传参数也可以用作事件订阅者执行方法的区分通知
            case R.id.panhouye:
            //这里发布事件出去(下同)
                EventBus.getDefault().post(new MessageEvent("伐木机"));
                break;
            case R.id.bikonghai:
                EventBus.getDefault().post(new MessageEvent("影魔"));
                break;
            case R.id.postSticky:
             //粘性事件发布(事件发布后,可能目标组件还没有注册事件,然后当目标组件在某个地方注册事   
             //件时,该注册事件仍然能够接受到注册之前已经发布的事件)               
                EventBus.getDefault().postSticky(new MessageEvent("撼地神牛"));
                startActivity(new Intent(this,SecondActivity.class));
                break;
        }
    }
    //在主线程中订阅,即在主线程中处理该事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
//        //(1)将事件发布者发布的数据作为文本修改内容
//        msgFragment.setText(event.data);
        //(2)将事件发布者发布的数据作为方法执行的区分
        switch(event.data){
            case "伐木机":
                msgFragment.setText("转盘");
                break;
            case "影魔":
                msgFragment.setText("影压");
                break;
        }
    }
}

替换掉fragmelayout的fragment代码如下:

/**
 * Created by firesmog on 2017/3/14.
 */

public class MsgFragment extends Fragment {
    TextView tv;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_msg,container,false);
        tv = (TextView) view.findViewById(R.id.tv);
        return view;
    }
    public void setText(String message){
        tv.setText(message);
    }
}

SecondActivity代码如下:

public class SecondActivity extends AppCompatActivity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        tv = (TextView) findViewById(R.id.tv);
    }
    @Override
    protected void onResume() {
        super.onResume();
        EventBus.getDefault().register(this);
    }
    @Override
    protected void onPause() {
        super.onPause();
        EventBus.getDefault().unregister(this);
    }
    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onMessageEvent(MessageEvent event) {
//        //(1)将事件发布者发布的数据作为文本修改内容
        tv.setText(event.data);
//        }
    }
}

在demo中,还可以在fragment中注册eventbus并对时间进行订阅处理,实现activity中点击事件传递数据,在fragment中消费。这里感兴趣的可以做一下。

四、结束语

这个demo本身还是比较简单的,代码也都贴了出来,此处就不提供源码了,复制粘贴就可以使用,这里主要是初步了解eventbus的使用,希望大家一起成长学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值