Android框架篇 EventBus

Posted 彭老希

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android框架篇 EventBus相关的知识,希望对你有一定的参考价值。

一、前言

EventBus能够简化各组件间的通信,有效的分离事件发送方和接收方(解耦),避免复杂和容易出错的依赖性和生命周期问题。

三要素:
1、Event 事件:它可以是任意类型。
2、Subscriber 事件订阅者:在EventBus3.0之后事件处理的方法名可以随意取,但需要加上注解@Subscribe(),并且指定线程模型,默认是POSTING。
3、Publisher 事件的发布者:我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可

二、四种线程模型

1、POSTING (默认) 表示事件处理函数的线程发布事件的线程在【同一个线程】

无论在哪个线程,处理与发布是一起的

2、MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。

在主线程处理事务,不能进行耗时操作

3、BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。

你在主,我便另外开一个子线程,你如果在子线程,我就去到你的子线程里面跟你一起

4、ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

无论你在哪个地方(主线程或者子线程),我都另外自己开一个来运行

三、EventBus的基本用法

在Activity里注册EventBus事件,然后定义接收方法

1、自定义一个事件类

public class MessageEvent{
	//一、 需要接收什么样的信息,就定义什么变量属性,然后创建get/set方法
	//二、 需要接收什么样的信息,就定义什么变量属性,然后创建构造方法和get/set方法
    private String message;
    
    public  MessageEvent(String message){
        this.message=message;
    }
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

这个类是一个Bean类,里面定义用来传输的数据的类型。这样后面需要增添什么传输的信息,只需要修改这个Bean就可以了

2、注册事件

@Override
protected void onCreate(Bundle savedInstanceState) {           
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     EventBus.getDefault().register(this)} 

当我们需要在Activity或者Fragment里订阅事件时,我们需要注册EventBus。我们一般选择在Activity的onCreate()方法里去注册EventBus,在onDestory()方法里,去解除注册。

3、解除注册

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

也可以在你的基类BaseFragment / MyActivity里面去全局注册和解除注册,这样子类的活动或者碎片继承基类,就不用重复写这两行代码了。

4、发送事件

MessageEvent messageEvent = new MessageEvent("你需要发送的消息或者数据");
EventBus.getDefault().post(messageEvent);

5、处理事件

@Subscribe,并且要指定线程模型。 ThreadMode.MAIN 这个就是线程模型 MAIN 是替换项

@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
    // XXX 你可以随便命名
    // 参数 messageEvent 就是前面你发送的消息
    ...
}

四、EventBus用法之:粘性事件

所谓粘性事件,就是在发送事件之后再订阅该事件也能收到该事件。请注意这里与普通事件的区别,普通事件是先注册在绑定

实战需求,在FirstActivity发送事件,到SecondActivity中做事件的处理。

如果是使通过EventBus.getDefault.post(xx)发出的,在SecondActivity是接收不到消息的。

主要原因是SecondActivit用于接收消息的EventBus还未完成注册,也就是发布者发了消息,但订阅者还未产生。

1、发送粘性事件

MessageEvent messageEvent = new MessageEvent("你需要发送的消息或者数据");
EventBus.getDefault().postSticky(messageEvent);

2、处理粘性事件

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void XXX(MessageEvent messageEvent) {
    ...
}

剩下的注册操作和解绑操作和发送普通事件是一样的

五、 EventBus使用实战

第一步:添加依赖
 // EventBus 事件总线:https://github.com/greenrobot/EventBus
    implementation "org.greenrobot:eventbus:3.1.1"
第二步:定义消息事件类
public class MessageEvent{
    private String message;
    public  MessageEvent(String message){
        this.message=message;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}
第三步:注册和解除注册

分别在FirstActivity的onCreate()方法和onDestory()方法里,进行注册EventBus和解除注册。

public class FirstActivity extends AppCompatActivity {
    private Button mButton;
    private TextView mText;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_activity);
        mButton = (Button) findViewById(R.id.btn1);
        mText = (TextView) findViewById(R.id.tv1); 
        mText.setText("欢迎关注彭老希"); 
        EventBus.getDefault().register(this);
        jumpActivity();
    }

    private void jumpActivity() {

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void Event(MessageEvent messageEvent) {
        mText.setText(messageEvent.getMessage());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }

}

第四步:事件处理

事件的处理线程在主线程,是要让TextView去显示值
在 SecondActivity里去进行事件的发送。

public class SecondActivity extends AppCompatActivity {
    private Button mButton2;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);
        mButton2 = (Button) findViewById(R.id.btn2);
        jumpActivity();
    }

    private void jumpActivity() {
        mButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent("欢迎大家关注我"));
                finish();
            }
        });
    }
}

使用EventBus后逻辑将非常的清晰,并且代码之间高度解耦,在进行组件、页面间通信的时候,EventBus是一个不错的选择。

以上是关于Android框架篇 EventBus的主要内容,如果未能解决你的问题,请参考以下文章

Android EventBus框架之源码简单解析

Android EventBus源码解析, 带你深入理解EventBus

Android编程入门--开源框架EventBus

EventBus组件间通讯利器入门篇

Android之EventBus使用

android EventBus的简单使用