EventBus框架的使用

来源:互联网 发布:mac ai 毛笔字体 编辑:程序博客网 时间:2024/05/16 14:37

参考文章:http://blog.csdn.net/yuanzeyao/article/details/38174537

EventBus源码以及jar的下载地址:https://github.com/greenrobot/EventBus/tree/V3.0.0  http://download.csdn.net/detail/yy1300326388/8727699

       在android 项目开发中,事件传递我们一般使用handler ,broadcast 和receiver等,但是这些东西东西多起来就会比较烦。比如handler 基本在每一个activity中都会有一个 ,而且还要将它写成静态(不然容易引起内存泄露),使得我们的项目看起来非常的不爽。于是EventBus开源框架就出来了。当我开始使用EventBus后,一个字爽,老子再也不要用什么startActivityforResult,handler,大量的广播等等一些操蛋东西了。吐槽完毕下面简单的介绍一下EventBus的四个订阅函数.

onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEvnetBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.

简单介绍完EventBus咱们开始去学习EventBus的使用。

1.如果你想在所有的activity或者fragment中使用,建议写一个BaseActivity,下面是我写的一个简单的BaseActivity

package com.mao.activity;import com.mao.event.FinishEvent;import de.greenrobot.event.EventBus;import android.os.Bundle;import android.support.v4.app.FragmentActivity;public class BaseActivity extends FragmentActivity{@Overrideprotected void onCreate(Bundle arg0) {// TODO Auto-generated method stubsuper.onCreate(arg0);register();}public void register(){EventBus.getDefault().register(this);}@Overrideprotected void onDestroy() {super.onDestroy();EventBus.getDefault().unregister(this);}public void onMainEventThread(FinishEvent finishEvent){finish();}}
其中register方法为注册观察者,在oncreate方法中调用,为什么要写成一个方法呢?因为注册有多种多样,比如延时注册,优先级等等。想要使用不同的注册方法,重写这个方法即可,和广播服务一样,注册了就得取消注册,咱们在ondestroy中取消注册。

在baseactivity中我还写了一个onMainEventThread方法,这就是上文所说的订阅函数。主要作用就是,我们想要退出整个app的时候发出一个退出消息即可。细心的朋友一定看到了onMainEventThread的参数,没错这个类就是相当于一个标记,比如你在某一个avtivity中发出了消息

EventBus.getDefault().post(new FinishEvent());
<pre name="code" class="java"><span style="font-size:18px;">发送消息有两种,一种是post(),另外一种是postSticky(),post发出消息不会保留,<span style="font-family: Arial, Helvetica, sans-serif;">postSticky会将消息保留到消息队列中,比如你的activity还没有被激活,使用post发消息,activity激活后是收不到消息的,而</span></span><pre name="code" class="java"><span style="font-size:18px;">postSticky能够收到消息。</span>

<pre name="code" class="java">
<span style="font-size:18px;">这时候订阅函数的参数只要是FinishEvent都会收到这消息,从而执行相应的操作,这里是关闭所有activity.FinishEvent如下:</span>
<pre name="code" class="java">package com.mao.event;public class FinishEvent {}


这里是一个空类,起到的作用仅仅是一个标记而已,这个类也可以加上各种各样的属性但是必须要有get set方法。

2.使用EventBus实现handler,线程的功能。

有时候我们需要在子线程中做了某个操作之后,发出message告诉handler来更新UI,使用EventBus也能实现相应的功能,而且更方便,代码耦合更低。

下面我们使用EventBus实现这个简单的功能。

package com.mao.activity;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import com.example.unit11_test_3.R;import com.iotek.service.aidl.IPerson;import com.iotek.service.aidl.Person;import com.mao.event.AsyncOnclickEvnet;import com.mao.event.onClickEvent;import de.greenrobot.event.EventBus;public class MainActivity extends BaseActivity implements OnClickListener{Button btn_one_second,btn_two_second,btn_three_second;TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn_one_second=(Button)findViewById(R.id.btn_one_second);btn_two_second=(Button)findViewById(R.id.btn_two_second);btn_three_second=(Button)findViewById(R.id.btn_three_second);tv=(TextView)findViewById(R.id.textView1);btn_one_second.setOnClickListener(this);btn_two_second.setOnClickListener(this);btn_three_second.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_one_second:EventBus.getDefault().post(new AsyncOnclickEvnet(1));break;case R.id.btn_two_second:EventBus.getDefault().post(new AsyncOnclickEvnet(2));break;case R.id.btn_three_second:EventBus.getDefault().post(new AsyncOnclickEvnet(3));break;default:break;}}public void OnEvnetMainThread(onClickEvent onClickEvent){switch (onClickEvent.getAction()) {case 1:tv.setText("1秒以後修改的");break;case 2:tv.setText("2秒以後修改的");break;case 3:tv.setText("3秒以後修改的");break;default:break;}}public void onEventAsync(AsyncOnclickEvnet asyncOnclickEvnet){switch (asyncOnclickEvnet.getAction()) {case 1:try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}EventBus.getDefault().post(new onClickEvent(1));break;case 2:try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}EventBus.getDefault().post(new onClickEvent(2));break;case 3:try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}EventBus.getDefault().post(new onClickEvent(3));break;default:break;}}}


上面是我们MainActivity,主要实现功能就是点击按钮,一秒之后,两秒之后,三秒之后修改TextView的文本。

在Mainactivity中onMainEventThread()相当于我们的handler,onEventAsync相当子线程。传递消息的标记就是OnclickEvnet 和AsyncOnclickEvnet.OnclickEvnet 如下:

package com.mao.event;public class onClickEvent {private int action;public int getAction() {return action;}public void setAction(int action) {this.action = action;}public onClickEvent(int action) {this.action=action;}public onClickEvent() {}}
我添加了一个action属性,以便于知道是哪个按钮被点击了。当我们post一个消息,EventBus会通过反射将我们对象给订阅函数。然后我们通过判断action的值就可以知道是点击的哪个按钮,这里的OnclickEvnet 大家可以将他看成handler中的message,同样也可以传递Object对象。

例子讲完了,在上面我们只使用了两个订阅函数,但是其他的两个也是差不多的,只要掌握了这两个其他两个使用起来一样一样的。下面说几个我使用我过程中遇到的小问题。

1、注意我们传递参数的类一定要写成javaBean的形式,也就是必须要有get set方法。

2、一个注册了EventBus事件的类必须要有一个订阅函数,否则报的错误会让你怀疑人生。(我就因为写错了一个单词将onMainEventThread写成onMianEventThread,找了整整一个小时哭

3、同样的订阅函数可以有多个,只要参数不同即可,比如onMainEventThread你爱写多少个就可以写多少个只要Event不同微笑

4、注册之后一定要记得反注册,否则怎么死的都知道大哭

5、一定不要注册两次,否则会RuntimeException,这个运行的时候就会提示你。

到这里也就结束了,这是我第一个次写博客,有理解不恰当或者错误的地方望各位大牛指正微笑。想要更深层次的了解EventBus可以看这篇文章http://blog.csdn.net/yuanzeyao/article/details/38174537


1 0
原创粉丝点击