美文网首页
EventBus学习记录

EventBus学习记录

作者: 打工崽 | 来源:发表于2021-03-19 18:07 被阅读0次

学习原因

为了简化并且高质量地在Activity、Fragment、Thread、Service之间通信,解决高耦合的同时仍能继续高效地通信,有了事件总线的设计。

EventBus三要素

  1. Event:事件:可以是任何类型的对象
  2. Subscriber:事件订阅者。在EventBus3.0之前消息处理的方法只能限定于onEvent,onEventMainThread,onEventBackgroundThread和onEventAsync,分别对应四种线程模型。而EventBus3.0之后,事件处理的方法可以随便取名,但是许哟添加一个注解@Subscribe,并且指定线程模型(默认为POSTING)。
  3. Publisher:事件发布者。可以在任意线程任意位置发送事件,直接调用EventBus的post(Object)方法,可以自己实例化EventBus对象,但一般使用EventBus.getDefault()就可以,根据post函数参数的类型,会自动调用订阅相应类型事件的函数

EventBus四种线程模型

  1. POSTING:如果使用事件处理函数指定了线程模型为POSTING,那么该事件是在哪一个线程发布出来的,事件函数就会在哪个线程中运行,也就是说发布事件和接收事件在同一个线程中。此模型下要避免耗时操作,会阻碍事件传递,甚至有可能引起ANR
  2. MAIN:事件的处理会在UI线程中执行,事件处理的时间不能太长,长了会导致ANR
  3. BACKGROUND:如果事件说是在UI线程中发布出来的,那么该事件处理函数会在新的线程中运行;如果事件本来就是在子线程中发布出来的,那么该事件的处理函数直接在发布事件的线程中执行,在此事件处理函数中禁止进行UI更新操作
  4. ASYNC:无论事件在哪个线程中发布,该事件处理函数都会在新建的子线程中执行;同样此事件处理函数中禁止执行UI更新操作

EventBus基本用法5个步骤

  1. 自定义一个事件类
public class MessageEvent{
...
}
  1. 在需要订阅事件的地方注册事件
EventBus.getDefault().register(this);
  1. 发送事件
EventBus.getDefault().post(messageEvent);
  1. 处理事件
@Subscribe(thread = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent){
...
}
  1. 取消事件订阅
EventBus.getDefault().unregister(this);

简单案例

配置文件

implementation 'org.greenrobot:eventbus:3.0.0'

定义消息事件类MessageEvent

class MessageEvent {
    private String Message;

    public String getMessage() {
        return Message;
    }

    public void setMessage(String message) {
        Message = message;
    }

    public MessageEvent(String message) {
        Message = message;
    }
}

MainActivity中注册和取消订阅事件

public class MainActivity extends AppCompatActivity {
    private TextView tv_message;
    private Button bt_message;
    private Button bt_subscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_message = (TextView)findViewById(R.id.tv_message);
        bt_subscription = (Button)findViewById(R.id.bt_subscription);
        bt_message = (Button)findViewById(R.id.bt_message);

        bt_message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,SecondActivity.class));
            }
        });

        bt_subscription.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().register(MainActivity.this);
            }
        });
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        //取消注册事件
        EventBus.getDefault().unregister(this);
    }

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

}

MainActivity对应activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>

    <Button
        android:id="@+id/bt_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="跳转到SecondActivity"/>

    <Button
        android:id="@+id/bt_subscription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="注册事件"/>

</LinearLayout>

SecondActivity发布事件

public class SecondActivity extends AppCompatActivity {

    private Button bt_message;
    private TextView tv_message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        tv_message = (TextView)findViewById(R.id.tv_message);
        bt_message = (Button)findViewById(R.id.bt_message);
        bt_message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent("欢迎关注简书"));
                finish();
            }
        });
    }
}

SecondActivity对应activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <TextView
        android:id="@+id/tv_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SecondActivity"/>

    <Button
        android:id="@+id/bt_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送事件"/>

</LinearLayout>

proGuard加入混淆规则

-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);
}

此时我们点击MainAc中的“注册事件”按钮来注册事件,然后点击“跳转到SecondActivity”,这时跳转到SecondAc,接下来点击“发送事件”按钮,此时这个SecondAc被finish,同时可以看到MainAc中的TextView被修改,即MainAc成功接收了SecondAc发送的事件。


EventBus黏性事件

上述为普通事件,即要先注册订阅才可以收到发送的消息,黏性事件意为在发送消息之后再订阅也可以收到消息,修改的代码不多,只需要在activity_second.xml中新加入一个Button

<Button
        android:id="@+id/bt_subscription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送粘性事件"/>

然后在MainActivity中新加入一个自定义方法用来绑定黏性事件

@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
    public void  ononMoonStickyEvent(MessageEvent messageEvent){
        tv_message.setText(messageEvent.getMessage());
    }

最后在SecondActivity中绑定Button的点击事件即可

private Button bt_subscription;
bt_subscription = (Button)findViewById(R.id.bt_subscription);
        bt_subscription.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().postSticky(new MessageEvent("粘性事件"));
                finish();
            }
        });

此时运行我们可以直接跳转到SecondAc而不注册,跳转后点击“发送黏性事件”,SecondAc被finish掉后回到MainAc,此时点击“注册事件”我们可以发现MainAc中的TextView被修改了,完成了黏性事件的发送。


此文仅为个人学习笔记,不以盈利为目的,摘抄自《Android进阶之光——刘望舒》,文字与代码纯手敲完成。


欢迎指正。

相关文章

网友评论

      本文标题:EventBus学习记录

      本文链接:https://www.haomeiwen.com/subject/dzuvcltx.html