<Android>greenrobot-EventBus,guava-Event Bus的异步实现
刚開始是从otto入手,可是otto不支持异步运行。所以后来才開始研究了Event Bus。关于Event Bus,先前搜索的时候,看到网上的实例,非常碎,并且非常多都是一样的内容,代码看下来基本上是分2套写法。这就带来了疑问。后来再细致浏览原先的帖子发现了Event Bus有2套源代码。一个是greenrobot的Event Bus,一个是google的guava Event Bus。今天谈论的并非2套Event Bus的原理以及不同之处,这些内容基本在网上都有參考,临时不在这里累赘介绍了。等有时间深入研究的时候能够再写一遍具体的Event
Bus的介绍。这次基本的是介绍2套Event Bus的异步实现,网上中文页面搜索基本非常少有Event Bus异步的介绍,有的话也是非常easy的代码实例,并且仅仅有抛事件的代码,尝试过后都是失败的,最后都是在外文站点上搜索到了关键的代码,好了不废话。直接上代码。
首先介绍的是greenrobot Event Bus,
package com.benny.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import de.greenrobot.event.EventBus;
public class MyEventByusTestActivity extends Activity implements OnClickListener {
private EventBus eventBus = EventBus.getDefault();
private LinearLayout viewGroup;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewGroup = (LinearLayout)findViewById(R.id.main_layout);
// button设置响应接口
findViewById(R.id.postthread).setOnClickListener(this);
findViewById(R.id.mainthread).setOnClickListener(this);
findViewById(R.id.backgroundthread).setOnClickListener(this);
findViewById(R.id.async).setOnClickListener(this);
}
@Override
protected void onPause() {
super.onPause();
// 注销事件响应
eventBus.unregister(this);
}
@Override
protected void onResume() {
super.onResume();
// 注冊事件响应
eventBus.register(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.postthread:
// 抛出PostThread模式的LoadButtonEvent事件
eventBus.post(loadButtonList("postthread", 30));
break;
case R.id.mainthread:
// 抛出MainThread模式的LoadLineEvent事件
eventBus.post(loadLineList(20));
break;
case R.id.backgroundthread:
// 抛出BackgroundThread模式的LoadNoneEvent事件
eventBus.post(new LoadNoneEvent());
break;
case R.id.async:
// 抛出Async模式的LoadAsyEvent事件
eventBus.post(new LoadAsyEvent());
break;
default:
break;
}
}
public LoadEvent loadTextList(String str, int num) {
ArrayList<TextView> list = new ArrayList<TextView>(num);
for (int i = 0; i < num; i++) {
TextView textView = new TextView(this);
textView.setText(str + i);
list.add(textView);
}
return new LoadEvent(list);
}
public LoadLineEvent loadLineList(int num) {
ArrayList<View> list = new ArrayList<View>();
for (int i = 0; i < num; i++) {
View view = new View(this);
view.setBackgroundColor(Color.BLUE);
list.add(view);
}
return new LoadLineEvent(list);
}
public LoadButtonEvent loadButtonList(String str, int num) {
ArrayList<Button> list = new ArrayList<Button>();
for (int i = 0; i < num; i++) {
Button button = new Button(this);
button.setText(str + i);
list.add(button);
}
return new LoadButtonEvent(list);
}
// 以PostThread的方式接受LoadButtonEvent事件
public void onEvent(LoadButtonEvent event) {
Log.d("EventBus", "load post thread");
addButtonViews(event);
}
// 以MainThread的方式接受LoadLineEvent事件
public void onEventMainThread(LoadLineEvent event) {
Log.d("EventBus", "load main thread");
addLineViews(event);
}
// 以BackgroundThread的方式接受LoadNoneEvent事件
public void onEventBackgroundThread(LoadNoneEvent event) {
Log.d("EventBus", "load background thread");
LoadEvent loadE = loadTextList("backgroundthread", 500);
// 抛出MainThread模式的LoadEvent事件用来更新界面
eventBus.post(loadE);
}
// 以Async的方式接受LoadAsyEvent事件
public void onEventAsync(LoadAsyEvent event) {
Log.d("EventBus", "load async");
LoadEvent loadE = loadTextList("async", 1000);
// 抛出MainThread模式的LoadEvent事件用来更新界面
eventBus.post(loadE);
}
// 以MainThread的方式接受LoadEvent事件
public void onEventMainThread(LoadEvent event) {
addTextViews(event);
}
private void addLineViews(LoadLineEvent event) {
viewGroup.removeAllViews();
for (View view : event.list) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 20);
viewGroup.addView(view, param);
}
}
private void addButtonViews(LoadButtonEvent event) {
viewGroup.removeAllViews();
for (Button button : event.list) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
viewGroup.addView(button, param);
}
}
private void addTextViews(LoadEvent event) {
viewGroup.removeAllViews();
for (TextView view : event.list) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
viewGroup.addView(view, param);
}
}
class LoadEvent {
List<TextView> list;
public LoadEvent(List<TextView> list) {
this.list = list;
}
}
class LoadLineEvent {
List<View> list;
public LoadLineEvent (List<View> list) {
this.list = list;
}
}
class LoadButtonEvent {
List<Button> list;
public LoadButtonEvent(List<Button> list) {
this.list = list;
}
}
class LoadNoneEvent {
}
class LoadAsyEvent {
}
}
界面事实上非常easy。四个button,分别为R.id.postthread,R.id.mainthread,R.id.backgroundthread,R.id.async。这个是分别针对Event Bus中ThreadMode的四种模式:PostThread,MainThread,BackgroundThread,Async。
PostThread —— 直接将事件抛在当前的线程中。
MainThread —— 将事件抛在主线程中(UI线程)。
BackgroundThread —— 将事件抛在新的线程中。
Async —— 将事件抛在异步线程中。
viewGroup是一个在ScrollView以下的LinearLayout布局。
greenrobot Event Bus,其固定的接受事件代码是
public void onEvent(AnyEvent event) -- PostThread
public void onEventMainThread(AnyEvent event) -- MainThread
public void onEventBackgroundThread(AnyEvent event) -- BackgroundThread
public void onEventAsync(AnyEvent event) -- Async
事实上另一种方法,能够直接定义事件接受的方法。
可查看EventBus中的代码 public void register(Object subscriber, String methodName, Class<?> eventType, Class<?>... moreEventTypes)
methodName -- 能够是自定义的方法名,能够全然代替"onEvent",至于4种模式相同能够区分,methodName仅仅须要前缀。譬如传递的參数是loadEvent。而代码中的方法是public void loadEventAsync(AnyEvent event),则表示是通过Async抛出的事件。以此类推。
Class<?> eventType, Class<?>... moreEventTypes -- 是于事件相关的一些參数。
也能够通过阅读EventBus的源代码来获取很多其它的信息。
在BackgroundThread,Async模式中,最后假设要刷新界面的话。他们还是须要在以MainThread的模式抛出刷新界面的事件。
greenrobot Event Bus下载地址:https://github.com/greenrobot/EventBus
接着介绍guava Event Bus。
package com.benny.test;
import java.util.concurrent.Executor;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class GuavaEventBusDemoActivity extends Activity implements OnClickListener {
// 创建异步的EventBus
private EventBus asyBus = new AsyncEventBus(new Executor() {
private Handler mHandler;
// 实现异步机制的事件处理
@Override
public void execute(Runnable command) {
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
mHandler.post(command);
}
});
private EventBus bus = new EventBus();
private LinearLayout viewGroup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewGroup = (LinearLayout)findViewById(R.id.main_layout);
findViewById(R.id.postthread).setOnClickListener(this);
findViewById(R.id.mainthread).setOnClickListener(this);
findViewById(R.id.backgroundthread).setOnClickListener(this);
findViewById(R.id.async).setOnClickListener(this);
}
@Override
protected void onPause() {
super.onPause();
// 注销事件订阅者
bus.unregister(this);
asyBus.unregister(this);
}
@Override
protected void onResume() {
super.onResume();
// 注冊事件订阅者
bus.register(this);
asyBus.register(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.postthread:
break;
case R.id.mainthread:
// 主线程抛LoadButtonEvent事件
bus.post(new LoadButtonEvent("main thread", 100));
break;
case R.id.backgroundthread:
break;
case R.id.async:
// 异步线程抛LoadTextEvent事件
asyBus.post(new LoadTextEvent("async", 1000));
break;
default:
break;
}
}
// 订阅LoadButtonEvent事件处理
@Subscribe
public void loadButtonList(LoadButtonEvent event) {
Log.d("Guava", "ButtonEvent" + event);
viewGroup.removeAllViews();
for (int i = 0; i < event.num; i++) {
Button button = new Button(this);
button.setText(event.str + i);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
viewGroup.addView(button, param);
}
}
// 订阅LoadTextEvent事件处理
@Subscribe
public void loadTextListAsync(LoadTextEvent event) {
Log.d("Guava", "TextEvent=" + event.str);
viewGroup.removeAllViews();
for (int i = 0; i < event.num; i++) {
TextView textView = new TextView(this);
textView.setText(event.str + i);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
viewGroup.addView(textView, param);
}
}
class LoadButtonEvent {
String str;
int num;
public LoadButtonEvent(String str, int num) {
this.str = str;
this.num = num;
}
}
class LoadTextEvent {
String str;
int num;
public LoadTextEvent(String str, int num) {
this.str = str;
this.num = num;
}
}
}
界面跟上一个实例是一样的,只是仅仅用到了2个button。MainThread和Asyncbutton。viewGroup是一个在ScrollView以下的LinearLayout布局。
异步的关键就在于
private EventBus asyBus = new AsyncEventBus(new Executor() {
private Handler mHandler;
// 实现异步机制的事件处理
@Override
public void execute(Runnable command) {
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
mHandler.post(command);
}
});
这样能够直接在异步事件后刷新界面。
guava Event Bus 下载地址:https://code.google.com/p/guava-libraries/
综合以上2个实例,这两种Event Bus的各自长处也非常明显,greenrobot Event Bus有四种模式抛出事件。guava Event Bus的异步实现比greenrobot来的方便,无需再抛MainThread事件了。源代码就不上了。大家动手写写能够加深印象。
<Android>greenrobot-EventBus,guava-Event Bus的异步实现的更多相关文章
- spring集成guava的event bus
Guava的event bus guava, https://github.com/google/guava 是一个非常有名的Java类库,提供了很多在日常开发中常用的集合.函数接口等.此外,guav ...
- EventBus / Event Bus
EventBus / Event Bus EventEmitter / Event Emitter https://greenrobot.org/eventbus/documentation/ htt ...
- 推荐 greenrobot eventbus,简化安卓开发,提高安卓维护性,优化安卓性能
最近在研究移动开发,广泛的阅读有关cordova,apicloud,android资料.发现安卓的开发还是很简单的.再发现greenrobot eventbus开源框架不仅可以简化安卓开发,有可以大幅 ...
- Android消息传递之EventBus 3.0使用详解
前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...
- Android中的eventBus传值
第一步:在build.gradle中添加依赖dependencies { compile 'org.greenrobot:eventbus:3.0.0'} 第二步:创建一个 Event类: 注意:en ...
- Android中的EventBus
1.分析 EventBus是一个针对Android的事件发布和订阅的框架,主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传 ...
- Android框架之EventBus的使用
简介 EventBus是由greenrobot组织贡献的一个Android事件发布/订阅的轻量级框架.EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用 ...
- 事件总线(Event Bus)知多少
源码路径:Github-EventBus 简书同步链接 1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集 ...
- 事件总线(Event Bus)
事件总线(Event Bus)知多少 源码路径:Github-EventBus简书同步链接 1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对 ...
随机推荐
- js模块化入门与commonjs解析与应用
JS模块化的基本原理 commonjs规范 commonjs在前端模块化中的基本使用 AMD与CMD规范剖析博客链接 一.JS模块化基本原理 在JS没有提出来模块化的时候,开发JS项目比较简单,同时也 ...
- svn 设置代理
Memory4Young Do Not Repeat Yourself! SVN —— 如何设置代理 如果在使用SVN下载外网的资源时,出现这样的提示:No such host is known. 或 ...
- 从零实现一个http服务器
我始终觉得,天生的出身很重要,但后天的努力更加重要,所以如今的很多“科班”往往不如后天努力的“非科班”.所以,我们需要重新给“专业”和“专家”下一个定义:所谓专业,就是别人搞你不搞,这就是你的“专业” ...
- vue 错误处理
https://sentry.io/for/vue/ https://cn.vuejs.org/v2/guide/deployment.html#跟踪运行时错误
- Django之学员管理
Django之学员管理 实现-------在前端页面提交的数据,后端可直接写入数据库.在页面实现操作数据库的增删改查. 数据表设计:(三个角色四张表) 班级表: id title 1 花果山国小一年级 ...
- RobotFramework:切换页面和Frame框架
切换页面主要有以下两种情况 在浏览器上打开多个窗口(Windows),在窗口内切换 打开多个浏览器(Browser),在多个浏览器内切换 1. 切换窗口 该操作适用于:打开两(多)个窗口页面,在打开的 ...
- ORACLE-023:令人烦恼的 ora-01722 无效数字
https://blog.csdn.net/yysyangyangyangshan/article/details/51762746
- 『NYIST』第八届河南省ACM竞赛训练赛[正式赛一]CF-236B. Easy Number Challenge
B. Easy Number Challenge time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- 在oracle下我们如何正确的执行数据库恢复
标签:oracle 数据库 恢复 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://jiujian.blog.51cto.com/4 ...
- [codeforces538E]Demiurges Play Again
[codeforces538E]Demiurges Play Again 试题描述 Demiurges Shambambukli and Mazukta love to watch the games ...