在做android开发的时候,免不了在各个组件之间进行通讯。它们之间的交互实在是比较麻烦,而且开销又或许很大。用BroadcastReceiver,还是Intenent呢?抑或者是handler,no no no,都不是,现在有一种轻量级的针对android通讯的优化的发布/订阅事件总线-----EventBus。它可以代替以上三者在组件之间,线程之间传递消息,代码间耦合度低,开销相对来说较小。
1.EventBus主要分为三部分:
(1)事件本身:暂且叫它待发布出去的信息吧
(2)事件发布者:用来发布一个事件
(3)事件订阅者:用来接收一个事件
2.EventBus的基本用法
(1)定义一个事件类,可以什么都不写,只是简简单单的一个类,如下:
public class DemoEvent {
}
(2)注册订阅事件
EventBus.getDefault().register(this);
(3)注销订阅事件
EventBus.getDefault().unregister(this);
(4)在订阅事件页面,实现接收事件的方法(共有4种)
public void onEventMainThread(DemoEvent event){
}
(5)发布一个事件,可以在任何地方
EventBus.getDefault().post(new DemoEvent());
以上就是EventBus最基本的用法了,大家可以随意开发使用的基础。
3.EventBus使用实战案例
基本框架的搭建是这样的:新建2个Activity,LauncherActivty和TestActivity,一个服务DemoService,以及一个事件类DemoEvent。在LauncherActivity和DemoService中注册订阅事件,并实现不同的接收方法onEventMainThread、onEventBackgroundThread和onEvent、onEventAsync,不同的方法里面都有不同的打印信息。在TestActivity中进行事件的发布,具体的代码如下:
(1)LauncherActivity
package com.example.eventbusdemo;
import de.greenrobot.event.EventBus;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class LauncherActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
//注册一个事件订阅者
EventBus.getDefault().register(this);
startService(new Intent(this,DemoService.class));
findViewById(R.id.startTestActivity).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(LauncherActivity.this,TestActivity.class));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销一个事件订阅者
EventBus.getDefault().unregister(this);
}
public void onEventMainThread(DemoEvent event){
Log.i("TAG", "receiver one event on onEventMainThread method in LauncherActivity.");
}
public void onEventBackgroundThread(DemoEvent event){
Log.i("TAG", "receiver one event on onEventBackgroundThread method in LauncherActivity.");
}
}
(2)DemoService
package com.example.eventbusdemo;
import de.greenrobot.event.EventBus;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class DemoService extends Service{
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
EventBus.getDefault().register(this);
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public void onEvent(DemoEvent event){
Log.i("TAG", "receiver one event on onEvent method in DemoService.");
}
public void onEventAsync(DemoEvent event){
Log.i("TAG", "receiver one event on onEventAsync method in DemoService.");
}
}
(3)TestActivity
package com.example.eventbusdemo;
import de.greenrobot.event.EventBus;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
findViewById(R.id.postEvent).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("TAG", "post one event in testActivity.");
EventBus.getDefault().post(new DemoEvent());
}
});
}
}
(4)运行结果如下:
4.EventBus实现方法介绍
上面是给大家演示了EventBus的基本功能,其中要实现的方法有4种,根据不同的情况可以去实现不同的方法,方法之间的区别说明如下:
(1)onEvent:一句话,事件是哪个线程发布的,onEvent就运行在哪个线程里面,也就是说发布和接收事件是在一个线程里面进行的。因此,在此方法里面不宜做耗时的操作,否则会造成分发事件的延迟哦。
(2)onEventMainThread:不论你在哪个线程里面发布事件,此方法都会运行在UI主线程里面,在主线程里接收事件。这个方法就很实用了,网络请求的时候,分分钟就能用到它。由于运行在主线程里面,所以耗时的操作也是不可以的,否则会造成ANR哦。
(3)onEventBackgroundThread:说白了,这个订阅方法一定是要运行在子线程里面的。如果你是在UI主线程里面发布的事件,那么它就会在一个新建的子线程里面运行,如果本身就是在一个子线程里面的发布的事件,那么它就会在发布事件的该线程中运行。
(4)onEventAsync:嗯,这个比较霸道,无论你在哪个线程里面发布的事件,都会新建一个子线程来运行此方法
5.总结
(1)一个事件的发布,可以被多个事件订阅函数(上面提到的4种不同接收方法)接收
(2)只要发布者和订阅者参数类型相同,即发布者post中类的实例和订阅函数中类的实例相同,就能建立以此通信