EventBus的使用

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

EventBus By曹艳明博客http:caoyanming.com

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

讲笑话应用的效果图 By曹艳明博客http:caoyanming.com

那怎样实现这样的小应用呢?我们先来了解一下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";
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定义了四个接收函数,分别是onEventMainThreadonEventPostThreadonEventBackgroundThreadonEventAsync,它们代表的意思依次是这个方法会在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和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.

本次 demo地址:https://bitbucket.org/magicshare/eventbusdemo/overview

博客:http://caoyanming.com/2014/10/09/EventBus%E8%AF%A6%E8%A7%A3.html


EventBus.jar下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值