27、AndroidEventBus

事件总线

EventBus

EventBus是一款针对Android优化的发布-订阅事件总线。它简化了应用程序内各组件间、组件与后台线程间的通信。其优点是开销小,代码更优雅,

以及将发送者和接收者解耦。

使用EventBus之前首先需要添加依赖:

implementation 'org.greenrobot:eventbus:3.1.1'

EventBus的混淆规则如下所示:

-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

使用EventBus

在使用EventBus之前,我们需要了解 EventBus 的三要素以及它的 4 种ThreadMode。

EventBus的三要素如下。

Event:事件。可以是任意类型的对象。
Subscriber:事件订阅者。在 EventBus 3.0 之前消息处理的方法只能限定于 onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,
它们分别代表4种线程模型。而在EventBus3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING)。
Publisher:事件发布者。可以在任意线程任意位置发送事件,直接调用 EventBus 的post(Object)方法。

EventBus的4种ThreadMode(线程模型)如下

POSTING(默认):该事件是在哪个线程发布出来的,事件处理函数就会在哪个线程中运行。
MAIN:事件的处理会在UI线程中执行。事件处理的时间不能太长,长了会导致ANR。
BACKGROUND:事件在UI线程发布,事件处理则会在新的线程中;事件本来在子线程发布,事件处理会在发布事件的线程中。(禁止更新UI)
ASYNC:无论事件在哪个线程中发布,该事件处理函数都会在新建的子线程中执行。(禁止更新UI)

EventBus基本用法

EventBus使用起来分为如下5个步骤:

1) 自定义一个事件类

public class MessageEvent {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
  1. 在需要订阅事件的地方注册事件
EventBus.getDefault().register(this);
  1. 发送事件,传递的参数为定义好的事件类
MessageEvent messageEvent = new MessageEvent();
messageEvent.setMessage("Hello EventBus");
EventBus.getDefault().post(messageEvent);
  1. 处理事件,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型
@Subscribe(threadMode = ThreadMode.MAIN)
public void eventBusOnUI(MessageEvent event) {
    Toast.makeText(MainActivity.this, event.getMessage(), Toast.LENGTH_SHORT).show();
}
  1. 取消事件订阅
EventBus.getDefault().unregister(this);

EventBus粘性事件

在activity_main.xml中编写如下布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_centerInParent="true"
        android:orientation="vertical">
        <Button
            android:id="@+id/btn_post"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送粘性事件" />
        <Button
            android:id="@+id/btn_regist"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="注册粘性事件"/>
    </LinearLayout>
</RelativeLayout>

在MainActivity.java中加入如下代码:

public class MainActivity extends AppCompatActivity {
    private Button mBtnPost;
    private Button mBtnRegist;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnPost = findViewById(R.id.btn_post);
        mBtnRegist = findViewById(R.id.btn_regist);
        // 发送粘性事件
        mBtnPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MessageEvent messageEvent = new MessageEvent();
                messageEvent.setMessage("粘性事件");
                EventBus.getDefault().postSticky(messageEvent);
            }
        });
        // 注册粘性事件
        mBtnRegist.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().register(MainActivity.this);
            }
        });
    }
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onMoonStickEvent(MessageEvent event) {
        Toast.makeText(MainActivity.this, event.getMessage(), Toast.LENGTH_SHORT).show();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

我们在未注册的情况下直接发送粘性事件后再注册来接收即可。

原文地址:https://www.cnblogs.com/pengjingya/p/14952194.html