美文网首页Android专题Android控件使用篇
EventBus—事件发布-订阅总线

EventBus—事件发布-订阅总线

作者: 千夜零一 | 来源:发表于2020-10-16 07:41 被阅读0次

    引言

      最近在了解RxBus,但被它取代的EventBus也需要熟悉啊,翻了很多的博客,要么讲的很官方,要么代码似是而非,小白根本看不懂啊,这可咋办?偷偷告诉你:“我也是小白!”
      于是就有了这篇文章:如何使用EventBus实现activity之间的事件分发-订阅。


    效果预览

    EventBus.gif

    介绍

      EventBus是一种用于Android的事件发布-订阅总线。它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。



    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,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起应用程序无响应(ANR)。
    (2)MAIN
      事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
    (3)BACKGROUND
      如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
    (4)ASYNC
      无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。


    用法

    第一步:添加依赖(app下build.gradle中)

    //EventBus 事件分发-订阅总线
    implementation 'org.greenrobot:eventbus:3.1.1'
    

    第二步:布局文件(ActivityA)

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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=".blog.ActivityA"
        tools:ignore="MissingConstraints">
        <Button
            android:id="@+id/btnIntent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="跳转到ActivityB"
            android:layout_margin="10dp"
            android:textSize="20sp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@id/tvMessage"
            app:layout_constraintVertical_chainStyle="packed"
            android:textAllCaps="false" />
        <TextView
            android:id="@+id/tvMessage"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:layout_margin="10dp"
            app:layout_constraintTop_toBottomOf="@id/btnIntent"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:text="接受ActivityB返回结果" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    布局文件(ActivityB中)

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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=".blog.ActivityB"
        tools:ignore="MissingConstraints">
        <Button
            android:id="@+id/btnSend"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="发送事件"
            android:textSize="20sp"
            android:layout_margin="10dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:textAllCaps="false" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    第三步:创建MessageEvent定义消息事件类

    package com.example.mydemo.entity;
    
    /**
     * @data on 2020/10/15 1:43 PM
     * @auther armstrong
     * @describe EventBus实战->定义消息事件类
     */
    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;
        }
    }
    

    第四步:在Activity中书写业务逻辑(ActivityA中)

    Tips:
      下面的点击事件中,我用到了java8中的特性:Lambda表达式,从而省略了重写点击事件的匿名内部类,你可以采用传统的写法new 完OnClickListener重写onClick方法,也可以看我的这篇文章:Lambda表达式告别@override,完成Lambda配置,从而简化你的代码。

    //EventBus事件发布-订阅总线探究
    public class ActivityA extends AppCompatActivity {
        private Button btnIntent;
        private TextView tvMessage;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_a);
            //EventBus事件发布-订阅总线
            initView();
        }
        private void initView(){
            btnIntent = findViewById(R.id.btnIntent);
            tvMessage = findViewById(R.id.tvMessage);
            tvMessage.setText("千夜零一");
            //注册
            EventBus.getDefault().register(this);
            //点击事件
            btnIntent.setOnClickListener((View)->{   
                startActivity(new Intent(this,ActivityB.class));
            });
        }
        @Subscribe(threadMode = ThreadMode.MAIN)  //事件订阅者
        public void Event(MessageEvent messageEvent){
            tvMessage.setText(messageEvent.getMessage());
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if(EventBus.getDefault().isRegistered(this)){
                EventBus.getDefault().unregister(this);
            }
        }
    }
    

    在Activity中书写业务逻辑(ActivityB中)

    //用作EventBus订阅-发布事件总线实战
    public class ActivityB extends AppCompatActivity {
        private Button btnSend;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_b);
            initView();
        }
        private void initView(){
            btnSend = findViewById(R.id.btnSend);
            btnSend.setOnClickListener((View)->{
                EventBus.getDefault().post(new MessageEvent("这是我的EventBus演示"));
                finish();
            });
        }
    }
    

    大功告成!


    总结

    EventBus在onCreate()方法中注册事件后,需要在onDestory()方法中解注册。

    相关文章

      网友评论

        本文标题:EventBus—事件发布-订阅总线

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