gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
阅读:5754回复:3

Vue EventBus使用详解

楼主#
更多 发布于:2020-03-25 14:02
EventBus是针一款对Android的发布/订阅事件总线。它可以让我们很轻松的实现在Android各个组件之间传递消息,并且代码的可读性更好,耦合度更低。


如何使用

(1)首先需要定义一个消息类,该类可以不继承任何基类也不需要实现任何接口。如:

   public class MessageEvent {
      ......
   }

(2)在需要订阅事件的地方注册事件

    EventBus.getDefault().register(this);

(3)产生事件,即发送消息

    EventBus.getDefault().post(messageEvent);

(4)处理消息

   @Subscribe(threadMode = ThreadMode.PostThread)
    public void XXX(MessageEvent messageEvent) {
    ...
    }
     在3.0之前,EventBus还没有使用注解方式。消息处理的方法也只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,分别代表四种线程模型。而在3.0之后,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为PostThread),四种线程模型,下面会讲到。

     注意,事件处理函数的访问权限必须为public,否则会报异常。
(5)取消消息订阅

   EventBus.getDefault().unregister(this);
gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
沙发#
发布于:2020-03-25 14:15


有何优点


采用消息发布/订阅的一个很大的优点就是代码的简洁性,并且能够有效地降低消息发布者和订阅者之间的耦合度。
 举个例子,比如有两个界面,ActivityA和ActivityB,从ActivityA界面跳转到ActivityB界面后,ActivityB要给ActivityA发送一个消息,ActivityA收到消息后在界面上显示出来。我们最先想到的方法就是使用广播,使用广播实现此需求的代码如下:
 首先需要在ActivityA中定义一个广播接收器:

public class MessageBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        mMessageView.setText("Message from SecondActivity:" + intent.getStringExtra("message"));
    }
}
还需要在onCreate()方法中注册广播接收器:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //注册事件
    EventBus.getDefault().register(this);
    //注册广播
    IntentFilter intentFilter = new IntentFilter("message_broadcast");
    mBroadcastReceiver = new MessageBroadcastReceiver();
    registerReceiver(mBroadcastReceiver, intentFilter);
    ......
}

然后在onDestory()方法中取消注册广播接收器:

@Override

protected void onDestroy() {
    super.onDestroy();
    ......
    //取消广播注册
    unregisterReceiver(mBroadcastReceiver);
}

最后我们需要在ActivityB界面中发送广播消息:




findViewById(R.id.send_broadcast).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String message = mMessageET.getText().toString();
        if(TextUtils.isEmpty(message)) {
            message = "defaule message";
        }
        Intent intent = new Intent();
        intent.setAction("message_broadcast");
        intent.putExtra("message", message);
        sendBroadcast(intent);
    }
});







看着上面的实现代码,感觉也没什么不妥,挺好的!下面对比看下使用EventBus如何实现。 根据文章最前面所讲的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;
    }
}
在ActivityA界面中我们首先需要注册订阅事件:



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

然后在onDestory()方法中取消订阅:


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




当然还要定义一个消息处理的方法:

@Subscribe(threadMode = ThreadMode.MainThread)
public void onShowMessageEvent(MessageEvent messageEvent) {
    mMessageView.setText("Message from SecondActivity:" + messageEvent.getMessage());
}




至此,消息订阅者我们已经定义好了,我们还需要在ActivityB中发布消息:

findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String message = mMessageET.getText().toString();
        if(TextUtils.isEmpty(message)) {
            message = "defaule message";
        }
        EventBus.getDefault().post(new MessageEvent(message));
    }
});





对比代码一看,有人会说了,这尼玛有什么区别嘛!说好的简洁呢?哥们,别着急嘛!我这里只是举了个简单的例子,仅仅从该例子来看,EventBus的优势没有体现出来。现在我将需求稍微改一下,ActivityA收到消息后,需要从网络服务器获取数据并将数据展示出来。如果使用广播,ActivityA中广播接收器代码应该这么写:



public class MessageBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //从服务器上获取数据
                ......
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //将获取的数据展示在界面上
                        ......
                    }
                });
            }
        }).start();
    }
}




看到这段代码,不知道你何感想,反正我是看着很不爽,嵌套层次太多,完全违反了Clean Code的原则。那使用EventBus来实现又是什么样呢?我们看一下。







@Subscribe(threadMode = ThreadMode.BackgroundThread)
public void onGetDataEvent(MessageEvent messageEvent) {
    //从服务器上获取数据
    ......
    EventBus.getDefault().post(new ShowMessageEvent());
}

@Subscribe(threadMode = ThreadMode.MainThread)
public void onShowDataEvent(ShowMessageEvent showMessageEvent) {
    //将获取的数据展示在界面上
    ......
}







对比一下以上两段代码就能很明显的感觉到EventBus的优势,代码简洁、层次清晰,大大提高了代码的可读性和可维护性。我这只是简单的加了一个小需求而已,随着业务越来越复杂,使用EventBus的优势愈加明显。作者:Lauren_Liuling
链接:https://www.jianshu.com/p/da9e193e8b03
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
板凳#
发布于:2020-03-25 14:15
gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1377
地板#
发布于:2020-03-25 14:17
游客


返回顶部