欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android EventBus3.x的使用详解

程序员文章站 2022-06-09 23:32:45
...

前言

在Android的日常开发中,我们经常会遇到进程和组件的通信问题。
一般我们可以使用广播,Handler等方式来处理。
但是广播存在麻烦,效率也不高,如果传递的数据是实体类需要序列化,那么很显然成本会有点高等问题。
Hander主要用于周期性消息传递,用于通信则会造成内存泄漏等诸多问题。
所以今天我们要介绍使用EventBus来解决这些问题。

EventBus

GitHub开源地址:https://github.com/greenrobot/EventBus

什么是EventBus?

EventBus是一款针对Android优化的发布/订阅事件总线。
简化了应用程序内各组件间、组件与后台线程间的通信。
优点是开销小,代码更优雅,以及将发送者和接收者解耦。

Android EventBus3.x的使用详解

EventBus的三个的元素

  1. Event:事件。可以是任意类型的对象。
  2. Subscriber:事件订阅者。在EventBus3.0之前消息处理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他们分别代表四种线程模型。而在EventBus3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING)。
  3. Publisher:事件发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。

EventBus的四种线程模型

上面三元素的时候提到过3.0之前是使用4个方法来对于四种线程模型,而3.0以后使用注解的方法指定线程模型。

  1. POSTING:(默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR
  2. MAIN:表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作
  3. BACKGROUND:表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
  4. ASYNC:表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作

EventBus3.0使用

Gradle引入
implementation 'org.greenrobot:eventbus:3.1.1'
事件实体
public static class MessageEvent { /* Additional fields if needed */ }
订阅事件
//注册,声明订阅者
@Override
 public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this);
 }

 //销毁防止重复注册和内存泄漏
@Override
 public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
 }
 //处理事件,并通过注释选择指定线程模式
@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {/* Do something */};
发布事件
EventBus.getDefault().post(new MessageEvent());

粘性事件

EventBus还支持发送黏性事件,跟黏性广播类似,就是在事件发布之后再订阅该事件也能收到该事件
一般用于接收事件的界面/进程可能没有运行,但是希望它能收到该事件。只需要设置在该界面/进程可以处理粘性事件。

处理粘性事件

在注解中添加sticky = true表明处理粘性事件。

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)  
public void onMessageEvent(MessageEvent event) {/* Do something */};
发布粘性事件

使用postSticky发布粘性事件。

EventBus.getDefault().postSticky(new MessageEvent());

Demo

该Demo演示了Activty与Fragment的通信。
Android EventBus3.x的使用详解Android EventBus3.x的使用详解

public class MsgEvent {
    private String msg;

    public MsgEvent(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
public class EventActivity extends AppCompatActivity {

    @BindView(R.id.rx)
    Button rx;
    @BindView(R.id.java)
    Button java;
    @BindView(R.id.android)
    Button android;
    @BindView(R.id.event_layout)
    FrameLayout eventLayout;
    private FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.event_layout, new EventFragment());
        transaction.commit();
    }

    @OnClick({R.id.rx, R.id.java, R.id.android})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.rx:
                startActivity(new Intent(this, RxActivity.class));
                break;
            case R.id.java:
                EventBus.getDefault().post(new MsgEvent("Java"));
                break;
            case R.id.android:
                EventBus.getDefault().post(new MsgEvent("Android"));
                break;
        }
    }

}
<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".EventActivity">


    <Button
        android:id="@+id/rx"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="go to rxbus" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/java"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Java" />

        <Button
            android:id="@+id/android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Android" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/event_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
public class EventFragment extends Fragment {
    @BindView(R.id.text)
    TextView text;
    Unbinder unbinder;
    private View view;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_event, container, false);
        unbinder = ButterKnife.bind(this, view);
        return view;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MsgEvent event) {
        text.setText(event.getMsg());
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        EventBus.getDefault().unregister(this);
    }
}
<?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:gravity="center_horizontal"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="EventFragment"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textSize="16sp" />
</LinearLayout>

代码

GitHub:https://github.com/Demo-DeMon/RxEventBus

参考

https://blog.csdn.net/itachi85/article/details/52205464

相关标签: EventBus