zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    

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

  • 相关阅读:
    代替gets()的新操作
    前缀和(一维与二维) 差分
    高精度(高精加,高精减,高精乘,高精除)
    提高cin cout的速度
    二分算法(以 数的范围 为例)
    归并排序(merge_sort)
    快速排序(quick_sort)
    由后缀表达式题目:stoi atoi 函数新发现
    Redis(二)
    每日算法练习(2020-1-11)
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14952194.html
Copyright © 2011-2022 走看看