关于EventBus使用总结
推荐两篇csdn博客:
(一)http://blog.csdn.net/harvic880925/article/details/40660137
(二)http://blog.csdn.net/harvic880925/article/details/40787203
下载EventBus的类库
源码:https://github.com/greenrobot/EventBus
使用EventBus不需要实现接口,不需要继承父类,只需要
//注册EventBus
EventBus.getDefault().register(this);
EventBus.getDefault().post(new Object("PostEvent"));
//取消注册EventBus
EventBus.getDefault().unregister(this);
就上面三个方法就可以实现跨线程之间的消息传递。
**比较精炼的介绍是:**EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
主要有onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync四个约定好了的回调方法,约定大于配置的经典用例。
并且这四个回调方法里面参数类型可以自定义,单只能传递一个参数对象。
就是比如你的public void onEvent(PostEvent event)方法里面的参数对象是PostEvent(这里这个对象就是个普通的类),那么你用EventBus.getDefault().post(new PostEvent(“PostEvent”)); 里面post出去的消息对象也必须是这个对象,该回调方法才能被执行到。
ps:这里也需要注意下回调方法的public作用域和void返回值也必须这样约定写,否则到时候没调用你都不知道怎么回事!
下面来具体讲解没种情况下处理方式:
/**
* 使用onEvent来接收事件,那么接收事件和分发事件在一个线程中执行
* @param event
*/
public void onEvent(PostEvent event)
{
Log.d("yzy", "OnEvent-->"+Thread.currentThread().getId());
}
当使用
EventBus.getDefault().post(new PostEvent("PostEvent"));
和
new Thread()
{
public void run() {
Log.d("yzy", "PostThread-->"+Thread.currentThread().getId());
EventBus.getDefault().post(new PostEvent("PostEvent"));
};
}.start();
上面两种方式post消息的时候在onEvent里面的回调线程是在一个线程里执行的,也就是说你在非主线程post的时候不能再onEvent里面更新UI操作。
/**
* 使用onEventMainThread来接收事件,那么不论分发事件在哪个线程运行,接收事件永远在UI线程执行,
* 这对于android应用是非常有意义的
* @param event
*/
public void onEventMainThread(MainEvent event)
{
Log.d("yzy", "onEventMainThread-->"+Thread.currentThread().getId());
}
当使用
EventBus.getDefault().post(new MainEvent("MainEvent"));
和
new Thread()
{
public void run() {
Log.d("yzy", "PostThread-->"+Thread.currentThread().getId());
EventBus.getDefault().post(new MainEvent("MainEvent"));
};
}.start();
上面两种方式post消息的时候在onEventMainThread里面的回调方法是在主线程中,也就是不管在UI线程post消息还是在非ui线程post消息最后都可以调用这个方法更新UI操作。
/**
* 使用onEventBackgroundThread来接收事件,如果分发事件在子线程运行,那么接收事件直接在同样线程
* 运行,如果分发事件在UI线程,那么会启动一个子线程运行接收事件
* @param event
*/
public void onEventBackgroundThread(BackEvent event)
{
Log.d("yzy", "onEventBackgroundThread-->"+Thread.currentThread().getId());
}
当使用
EventBus.getDefault().post(new BackEvent("BackEvent"));
和
new Thread()
{
public void run() {
Log.d("yzy", "PostThread-->"+Thread.currentThread().getId());
EventBus.getDefault().post(new BackEvent("BackEvent"));
};
}.start();
上面两种方式post消息的时候在onEventBackgroundThread里面的回调方法是在子线程中,这个和onEvent方法就一个区别,即ui线程post消息会开启一个子线程回调该方法。所以该方法不可以更新ui操作。
/**
* 使用onEventAsync接收事件,无论分发事件在(UI或者子线程)哪个线程执行,接收都会在另外一个子线程执行
* @param event
*/
public void onEventAsync(AsyncEvent event)
{
Log.d("yzy", "onEventAsync-->"+Thread.currentThread().getId());
}
当使用
EventBus.getDefault().post(new AsyncEvent("AsyncEvent"));
和
new Thread()
{
public void run() {
Log.d("yzy", "PostThread-->"+Thread.currentThread().getId());
EventBus.getDefault().post(new AsyncEvent("AsyncEvent"));
};
}.start();
上面两种方式post消息的时候在onEventAsync的回调方法是在和post线程不同的线程里执行,这个和onEvent方法就完全不同了。所以也不能更新ui操作。
上面列举了这么多情况,其实开发中遇到最多的就是实现onEventMainThread方法,更新UI操作。具体其他方法就要看需求了。
这里记录下项目用到的有必要记录下的用法
在Activity里的onKeyDown里拦截back事件,点击back的时候post一个消息取消正在下载中的任务和清除一些还来不及保存的数据等。
Activity里EventBus.getDefault().register(this); 注意这里注册就传了this,在onDestory里EventBus.getDefault().unregister(this); 也传this。然后在Activity里面调用了执行了个点击事件执行下载任务。new DownloadManager();
在DownloadManager里面也用EventBus.getDefault().register(this); 这里传的也是this,然后在DownloadManager里面写了个
public void onEventMainThread(UcEvent event)方法
但是很神奇的事情就是,在Activity里面执行post(new UcEvent(“”)); 竟然能在DownloadManager里面写的onEventMainThread方法里面执行到。能做到这点还有什么理由不让我对EventBus这个框架感兴趣呢,简直太方便了,可以解决之前遇到的很多问题,不需要写很多代码来处理逻辑了。
其实也比较好奇为什么不需要类似实现接口回调方法一样回调就可以实现异步线程之间消息的传递?具体为什么得去研究源码了,源码是最好的老师。
【关于EventBus使用总结】如有错误的地方,欢迎大家拍砖!