参考文章: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{
@Override
protected void onCreate(Bundle arg0) {
// TODO Auto-generated method stub
super.onCreate(arg0);
register();
}
public void register(){
EventBus.getDefault().register(this);
}
@Override
protected 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;
@Override
protected 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);
}
@Override
public 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 block
e.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中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