• EventBus详解


    1.前言

    EventBus是一款针对Android优化的发布/订阅事件总线。可以替代广播、startActivityForResult、Handler、异步回调等来实现各组件间、组件与后台线程间的通信。它的优点是开销小,代码更优雅,以及将发送者和接收者解耦。

    通常我们在使用EventBus的时候都是直接需要接收通信的Activity/Fragment中通过EventBus.getDefault().register(this)订阅事件,在需要发起通信的逻辑直接调用EventBus.getDefault().post(Object event)来发布事件。但是要是一个项目中有很多地方都使用EventBus来通信,比如重新登录后更新各个页面的登录状态,或者是接收到通知更新消息提示等,都这样直接使用的话代码重复率很高,并且呢,如果以后升级或者更换EventBus时,各个地方都要修改,这就比较麻烦了。因此我一般是将EventBus的发布和订阅封装到BaseActivity/BaseFragment中。

    gitHub地址

    2.概述

    2.1添加依赖

    implementation 'org.greenrobot:eventbus:3.1.1'

    2.2三要素

    • Event 事件。它可以是任意类型。
    • Subscriber 事件订阅者。在EventBus3.0之前我们必须定义以onEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe(),并且指定线程模型,默认是POSTING。
    • Publisher 事件的发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。

    2.3 四种线程模型

    EventBus3.0有四种线程模型,分别是:

    • POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
    • MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
    • BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
    • ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

    3.基本实用

    3.1定义事件

    public class EventMessage<T> {
        private int code;//消息类型
        private T data;//消息数据
    
        public EventMessage(int code,T data){
            this.code=code;
            this.data=data;
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        @Override
        public String toString() {
            return "EventMessage{" +
                    "code=" + code +
                    ", data=" + data +
                    '}';
        }
    }

    3.2注册事件

    @Override
    protected void onCreate(Bundle savedInstanceState) {           
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         EventBus.getDefault().register(this);
    }

    3.2解除注册

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    3.3发送事件

    //普通事件
    EventBus.getDefault().post(event);
    
    //粘性事件
    EventBus.getDefault().postSticky(event);

    3.4处理事件

    //普通事件处理
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onReceiveEvent(EventMessage msg){
    //处理事件
    }

    //粘性事件处理
    @Subscribe(threadMode = ThreadMode.MAIN,sticky=true)
    public void onReceiveStickyEvent(EventMessage msg){
    //事件处理
    }
    
    

    4.封装

    事件EventMessage:

    public class EventMessage<T> {
        private int code;//消息类型
        private T data;//消息数据
    
        public EventMessage(int code,T data){
            this.code=code;
            this.data=data;
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        @Override
        public String toString() {
            return "EventMessage{" +
                    "code=" + code +
                    ", data=" + data +
                    '}';
        }
    }

    事件类型:EventCode:

    /**
     * 消息类型
     */
    public class EventCode {
        //根据具体业务定义类型
        public static final int EVENT_A=1000;
        public static final int EVENT_B=1001;
        public static final int EVENT_C=1002;
        public static final int EVENT_D=1003;
        public static final int EVENT_E=1004;
    }

    EventBus封装:

    public class EventBusUtils {
        private EventBusUtils(){
    
        }
    
        /**
         * 注册EventBus
         * @param subscribver
         */
        public static void register(Object subscribver){
            EventBus eventBus=EventBus.getDefault();
            if(!eventBus.isRegistered(subscribver)){
                eventBus.register(subscribver);
            }
        }
    
    
        /**
         * 解除注册EventBus
         * @param subscriber
         */
        public static void unregister(Object subscriber){
            EventBus eventBus=EventBus.getDefault();
            if(eventBus.isRegistered(subscriber)){
                eventBus.unregister(subscriber);
            }
        }
    
        /**
         * 发送普通事件消息
         */
        public static void post(Object event){
            EventBus.getDefault().post(event);
        }
    
        /**
         * 发送粘性事件消息
         */
        public static void postSticky(Object event){
            EventBus.getDefault().postSticky(event);
        }
    /**
         * 移除所有的粘性订阅事件
         */
        public static void removeAllStickyEvents(){
            EventBus.getDefault().removeAllStickyEvents();
        }
    }

    案例:从MainActivity分别跳转FirstActivity和SecondActivity,跳转SecondActivity时发送粘性事件,返回到MainActivity时发送普通事件

    代码实战:

    BaseActivity:

    public abstract class BaseActivity extends AppCompatActivity {
    
        private String TAG="BaseActivity";
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayoutResId());
            initView();
            initData();
    
            if(isRegisteredEventBus()){//放到initView后面  防止 接收到event事件需要更新UI的时候 布局还未初始化完成
                EventBusUtils.register(this);
            }
    
        }
    
        @Override
        protected void onDestroy() {
            release();
            if(isRegisteredEventBus()){
                EventBusUtils.unregister(this);
            }
            super.onDestroy();
        }
    
        /**
         * 获取布局
         * @return 布局ID
         */
        protected abstract int getLayoutResId();
    
        /**
         * 初始化视图
         */
        protected void initView(){}
    
        /**
         * 初始化数据
         */
        protected void initData(){}
    
        /**
         * 释放资源
         */
        protected void release(){}
    
    
    
        /**
         * 是否注册事件分发
         * @return true:注册    false:不注册 默认不注册
         */
        protected boolean isRegisteredEventBus(){
            Log.e(TAG, "isRegisteredEventBus: 00000");
            return false;
        }
    
    }

    MainActivity:

    public class MainActivity extends BaseActivity implements View.OnClickListener {
    
        private String TAG="MainActivity";
        private TextView tv;
        private Button bt1,bt2;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        protected int getLayoutResId() {
            return R.layout.activity_main;
        }
    
        @Override
        protected void initView() {
            super.initView();
            tv=findViewById(R.id.tv);
            bt1=findViewById(R.id.bt1);
            bt2=findViewById(R.id.bt2);
            bt1.setOnClickListener(this);
            bt2.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
    
    
            switch (v.getId()){
                case R.id.bt1:
                    FirstActivity.startActivity(MainActivity.this);
                    break;
                case R.id.bt2:
                    EventMessage eventMessage=new EventMessage(EventCode.EVENT_E,"来自mainactivity的msg");
                    EventBusUtils.postSticky(eventMessage);
                    SecondActivity.startActivity(MainActivity.this);
                    break;
            }
        }
    
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void  onReceiveEvent(EventMessage msg){
            String m=(String) msg.getData();
            if(msg.getCode()==EventCode.EVENT_A){
                tv.setText(m);
            }else if(msg.getCode()==EventCode.EVENT_B){
                tv.setText(m);
            }
        }
    
        @Override
        protected boolean isRegisteredEventBus() {
            Log.e(TAG, "isRegisteredEventBus: 1111" );
            return true;
        }
    }

    FirstActivity:

    public class FirstActivity extends BaseActivity implements View.OnClickListener {
        private String TAG="FirstActivity";
        private TextView tv;
        private Button bt;
    
        /**
         * 启动activity
         */
        public static void startActivity(Activity srcActivity) {
            Intent intent=new Intent(srcActivity,FirstActivity.class);
            srcActivity.startActivity(intent);
        }
        @Override
        protected int getLayoutResId() {
            return R.layout.activity_first;
        }
    
        @Override
        protected void initView() {
            super.initView();
            tv=findViewById(R.id.tv);
            bt=findViewById(R.id.bt1);
            bt.setOnClickListener(this);
        }
    
        @Override
        protected void initData() {
            super.initData();
        }
        
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.bt1:
                    EventMessage msg=new EventMessage(EventCode.EVENT_A,"来自firstactivity的消息");
                    EventBusUtils.post(msg);
                    this.finish();
                    break;
            }
        }
    }

    SecondActivity:

    public class SecondActivity extends BaseActivity implements View.OnClickListener {
        private String TAG="SecondActivity";
        private TextView tv;
        private Button bt;
        public static void startActivity(Activity activity){
            Intent intent=new Intent(activity,SecondActivity.class);
            activity.startActivity(intent);
    
        }
    
    
        @Override
        protected int getLayoutResId() {
            return R.layout.activity_second;
        }
    
        @Override
        protected void initView() {
            super.initView();
            tv=findViewById(R.id.tv);
            bt=findViewById(R.id.bt1);
            bt.setOnClickListener(this);
        }
    
        @Override
        protected void initData() {
            super.initData();
        }
    
        @Override
        protected boolean isRegisteredEventBus() {
            return true;
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.bt1:
                    EventMessage msg=new EventMessage(EventCode.EVENT_B,"来自secondactivity的消息");
                    EventBusUtils.post(msg);
                    this.finish();
                    break;
            }
        }
        @Subscribe(threadMode = ThreadMode.MAIN,sticky=true)
        public void onReceiveEvent(EventMessage msg){
            Log.e(TAG, "onReceiveEvent: msg:"+msg.toString() );
            if (msg.getCode()==EventCode.EVENT_E){
                tv.setText((String)msg.getData());
            }
        }
    }

    5.注意

    1.在基类中封装时,注意注册EventBus放到初始化视图后面,防止收到粘性事件需要更新UI时 布局还未初始化玩  会报空指针异常

    6.参考

    EventBus的优雅封装

  • 相关阅读:
    isinstance函数
    Django之ORM那些相关操作
    Django ~ 2
    Django ~ 1
    Django详解之models操作
    Django模板语言相关内容
    livevent的几个问题
    客户端,服务器发包走向
    关闭客户端连接的两种情况
    std::vector<Channel2*> m_allChannels;容器,以及如何根据channelid的意义
  • 原文地址:https://www.cnblogs.com/wangjiaghe/p/10149447.html
Copyright © 2020-2023  润新知