您的位置:首页 > 移动开发 > Android开发

EventBus使用

2015-07-21 21:39 651 查看


EventBus使用

简介

EventBus是一款针对Android优化的发布/订阅事件总线。EventBus的功能类似于
观察者模式
,它在Android里的主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。优点是开销小,代码更优雅。下面的图片是对EventBus的调用过程的一个描述:



EventBus的使用非常简单,但完成的功能却很强大,可以说,有了EventBus,我们能够丢掉Handler,专心的做和业务相关的事情。并且我们通过EventBus可以写出很优雅的代码。最有说服力的莫过于实战了,我通过EventBus实现了一个讲笑话的小应用。笑话源使用的是图灵机器人(http://www.tuling123.com/openapi/)。我们点击讲笑话的按钮后,会开启一个线程请求图灵机器人的api,实现笑话的索取。最后,通过EventBus将图灵机器人返回的json数据发布出去。EventBus的接收函数会对json数据进行处理并在主线程中运行,最终显示在TextView中。效果如下:



那怎样实现这样的小应用呢?我们先来了解一下EventBus一般的使用步骤:

定义事件 :
public
class MyEvent()

注:实际上,EventBus是根据MyEvent的类型来建立发送者何接收者之间的联系,也就是说,事件的发出者发出一个MyEvent类型的事件,只有能够接受MyEvent类型的接收者才会进行显示。原则上,对于一个大的项目,我们最好定义一个抽象的Event类,以后所有的Event全部来继承此类。但对于小的项目,我们甚至可以不去定义Event,比如我们接下来要介绍的应用,我们把JSONObject类型作为事件类型。

注册:
EventBus.getDefault().register(this)


发布事件:
EventBus.getDefault().post(new
MyEvent())


接收事件:
public
void onEvent**(MyEvent myEvent)


实战

了解到整个过程,我们落实到这个实例的代码上。

首先,我们需要在MainActivity里对事件进行注册:
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

jokeTv = (TextView)findViewById(R.id.jokeTv);

//注册EventBus事件

EventBus.getDefault().register(this);

}


其次,是点击按钮的事件函数,我们需要在这里进行网络的请求和事件的发送:
/**

*

*@param view

*点击按钮后会向图灵机器人发起“讲笑话”的请求。

*/

public void tellJoke(View view){

new Thread(){


@Override

public void run() {

super.run();

try {

//发送EventBus事件

EventBus.getDefault().post(new JSONObject(NetUtil.getJoke()));

}catch (ClientProtocolException e) {

e.printStackTrace();

}catch (JSONException e) {

e.printStackTrace();

}catch (IOException e) {

e.printStackTrace();

}

};


}.start();

}


这里,我们封装了一个NetUtil类将图灵机器人返回的数据作进一步的包装。然后EventBus将一个JSONObject类型的事件进行发送。

NetUtil代码也不复杂,这是一个简单的HttpGet请求:
private static final String APIURL = " http://www.tuling123.com/openapi/api?key=2d6672ad4f23c2f29c87e63ecfa323dc";[/code] 
public static String getJoke() throws ClientProtocolException, IOException{

String result="";

String INFO = URLEncoder.encode("讲个笑话", "utf-8");

String requesturl = "http://www.tuling123.com/openapi/api?key=2d6672ad4f23c2f29c87e63ecfa323dc&info="+INFO;

HttpGet request = new HttpGet(requesturl);

HttpResponse response = new DefaultHttpClient().execute(request);

if(response.getStatusLine().getStatusCode() == 200){

result = EntityUtils.toString(response.getEntity());

}

return result;

}


接着,是事件的接收函数,它肯定需要一个JSONObject类型的参数:
//根据参数类型来接收事件

public void onEventMainThread(JSONObject jsonObject) {

try {

jokeTv.setText(jsonObject.get("text").toString());

}catch (JSONException e) {

e.printStackTrace();

}

}


最后,我们在onDestroy里将EventBus unregister掉。
@Override

public void onDestroy()

{

super.onDestroy();

// Unregister

EventBus.getDefault().unregister(this);

}


就这样,我们使用Eventbus实现了一个简单的Demo,它使用了网络请求,但是我们没有看到handler,没有volley,没有异步任务。有的只是几个简单的函数,可以说,如果设计的好,Eventbus能让Android代码更轻松的实现零耦合。

常见问题

说到这里大家可能会有一个疑问,Eventbus只是根据参数的类型将事件发送者何接收者联系起来的吗?还有其它的限制吗?事实上,Eventbus定义了四个接收函数,分别是
onEventMainThread
onEventPostThread
, 
onEventBackgroundThread
onEventAsync
,它们代表的意思依次是这个方法会在UI线程执行(onEventMainThread)、这个方法会在当前发布事件的线程执行(onEventPostThread)、这个方法,如果在非UI线程发布的事件,则直接执行,和发布在同一个线程中。如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用(onEventBackgroundThread)、这个方法会被加入后台任务队列,使用线程池调用,类似异步任务(onEventAsync)。在我们的实例中,我们使用的是onEventMainThread函数,表示我们发布的事件需要在主线程中执行。

还有一个小问题,就是如果我们同时在onEventMainThread和onEventPostThread两个函数里对JSONObject事件进行接收回怎么样呢?答案是运行时直接报错:de.greenrobot.event.EventBusException: Illegal onEvent method, check for typos: public void so.cym.eventbus.MainActivity.onEventPostThread(org.json.JSONObject)

Eventbus与Broadcast区别

说了这么多,你会发现,Eventbus和Android内部的Broadcast(广播)的机制很类似,关于这个问题,EventBus官方的回答如下:

Unlike Android’s BroadcastReceiver/Intent system, EventBus uses standard Java classes as events and offers a more convenient API. EventBus is intended for a lot more uses cases where you wouldn’t want to go through the hassle of setting up Intents,
preparing Intent extras, implementing broadcast receivers, and extracting Intent extras again. Also, EventBus comes with a much lower overhead.

项目源码

欢迎你到此处进行fork或者starhttps://gitcafe.com/saymagic/EventbusDemo

原文链接:http://blog.saymagic.cn/2014/10/09/EventBus详解.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android eventbus 使用