事件总线框架
针对事件提供统一订阅,发布以达到组件间通信的解决方案。
原理
观察者模式。
EventBus和Otto
先看EventBus的官方定义:
Android optimized event bus that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
再看Otto官方定义:
Otto is an event bus designed to decouple different parts of your application while still allowing them to communicate efficiently.
总之,简化android应用内组件通信。
对比BroadcastReceiver
在工作上,我在两个场景下分别使用过Otto和EventBus,一个是
下载管理器通知各个相关的Activity当前的进度,一个是设置应用壁纸。
单从使用上看,EventBus > Otto > BroadcastReceiver(当然BroadcastReceiver作为系统内置
组件,有一些前两者没有的功能).
EventBus最简洁,Otto最符合Guava EventBus的设计思路, BroadcastReceiver最难使用。
我个人的第一选择是EventBus。
实例:“设置壁纸”
两大的框架的基本使用都非常简单:
EventBus的基本使用官方参考:https://github.com/greenrobot/EventBus
Otto的基本使用官方参考:http://square.github.io/otto/
EventBus实现篇
EventBus规定onEvent方法固定作为订阅者接受事件的方法,应该是参考了“约定优于配置”思想。
定义EventModel,作为组件间通信传递数据的载体
public class WallpaperEvent {
private Drawable wallpaper;
public WallpaperEvent(Drawable wallpaper) {
this.wallpaper = wallpaper;
}
public Drawable getWallpaper() {
return wallpaper;
}
public void setWallpaper(Drawable wallpaper) {
this.wallpaper = wallpaper;
}
}
定义订阅者,最重要的是onEvent方法
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
initWallpaper();
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public void onEvent(WallpaperEvent wallpaperEvent) {
// AppConfig.sWallpaperDrawable as a global static var
AppConfig.sWallpaperDrawable = wallpaperEvent.getWallpaper();
initWallpaper();
}
private void initWallpaper() {
// support custom setting the wallpaper
// 根据AppConfig.sWallpaperDrawable,默认值等设置当前Activity的背景壁纸
// ...
}
}
通过post()方法在任何地方发布消息(壁纸,准确的说是WallpaperEvent)给所有的BaseActivity子类,举个例子:
private void downloadWallpapper(String src) {
ImageL```javaoader.getInstance().loadImage(src, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
BitmapDrawable wallpaper = new BitmapDrawable(loadedImage);
// presist the image url for cache
saveWallpaper(imageUri);
// notify all base activity to update wallpaper
EventBus.getDefault().post(new WallpaperEvent(wallpaper));
Toast.makeText(WallpapeEventBusrActivity.this,
R.string.download_wallpaper_success,
Toast.LENGTH_SHORT).show();
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
Toast.makeText(WallpaperActivity.this,
R.string.download_wallpaper_fail,
Toast.LENGTH_SHORT).show();
}
});
}
重点就是这句:
// 在任何地方调用下面的方法,即可动态全局实现壁纸设置功能
EventBus.getDefault().post(new WallpaperEvent(wallpaper));
Otto实现篇
这里要注意几点点:
(1)Otto使用注解定义订阅/发布者的角色,@Subscribe为订阅者,@Produce为发布者,方法名称就可以自定义了。
(2)Otto为了性能,代码意图清晰,@Subscribe,@Produce方法必须定义在直接的作用类上,而不能定义在基类而被继承。
(3)和EventBus不同的是,发布者也需要register和unregister,而EventBus的发布者是不需要的。
定义EventModel,作为组件间通信传递数据的载体
public class WallpaperEvent {
private Drawable wallpaper;
public WallpaperEvent(Drawable wallpaper) {
this.wallpaper = wallpaper;
}
public Drawable getWallpaper() {
return wallpaper;
}
public void setWallpaper(Drawable wallpaper) {
this.wallpaper = wallpaper;
}
}
避免浪费,相对于EventBus.getDefault(), Otto需要自己实现单例。
public class AppConfig {
private static final Bus BUS = new Bus();
public static Bus getInstance() {
return BUS;
}
}
定义订阅者,在接受事件的方法加上修饰符@Subscribe
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppConfig.getBusInstance().register(this);
initWallpaper();
}
@Override
protected void onDestroy() {
super.onDestroy();
AppConfig.getBusInstance().unregister(this);
}
public void onOttoEvent(WallpaperEvent wallpaperEvent) {
AppConfig.sWallpaperDrawable = wallpaperEvent.getWallpaper();
initWallpaper();
}
private void initWallpaper() {
// support custom setting the wallpaper
// 根据AppConfig.sWallpaperDrawable,默认值等设置当前Activity的背景壁纸
// ...
}
}
定义发布者,通过post()方法在任何地方发布消息了
public class WallpaperActivity extends BaseActivity {
private Drawable wallpaperDrawable;
//这里同时也要更新自己壁纸,所以显示定义@Subscribe的方法
@Subscribe
public void onWallpaperUpdate(WallpaperEvent wallpaperEvent) {
super.onWallpaperUpdate(wallpaperEvent);
}
@Produce
public WallpaperEvent publishWallPaper() {
return new WallpaperEvent(wallpaperDrawable);
}
private void downloadWallpapper(String src) {
//...
//通知所有@Subscribe匹配WallpaperEvent参数的方法执行
AppConfig.getBusInstance().post(publishWallPaper());
//...
}
}
小结
使用设计模式的思想解决问题,这才是设计模式的真正价值。
这两个android事件总线框架提供了一种更灵活更强大而又更加完美解耦的解决方案,在很多场合,从开发效率,执行性能和设计思路上都要优于BroadcastReceiver,值得学习使用。
分享到:
相关推荐
近段时间,事件总线(EventBus)技术貌似很火,小弟也膜拜了一下,虽然思想与技术都非常先进,但总感觉有什么不妥,首先是那几个onEvent…方法老记不住,要是写错怎么办,其次是接收方对于接收的事件也没有类型约定...
以新浪微博为例,在新浪微博首页好友动态列表页和好友动态...Android事件总线框架 AndroidEventBus 为此类需求的实现提供了非常方便的方案。 文章地址:http://blog.csdn.net/kpioneer123/article/details/51260660
别人那看来的,一个事件总线设计的初级demo,方便大家对事件总线进行理解
这是一个Android平台的事件总线框架, 它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。在往下看之前,你可以考虑...
你是否在开发的过程中遇到过想在Activity-B中回调Activity-A中的某个函数,但Activity又不能手动创建对象来设置一个Listener什么的?... 等等之类的组件之间的交互问题,事件总线框架就是你所需要的
带有语法强类型检查的事件总线EventBus框架例程.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
接前篇EventBus,在这一篇中,基于读写分离的思想完善了多线程操作的安装性,读和写不同的容器,采用双容器,写时写入后台容器,写完后交换到前台使用,这样做的好处是我们可以对容器进行并发的读,而不需要加锁,以...
基于 greenrobot 的 eventBus 使用 RxJava 实现的事件总线
EventBus是Android下高效的发布/订阅事件总线机制。作用是可以代替传统的Intent,Handler,Broadcast或接口函数在Fragment,Activity,Service,线程之间传递数据,执行方法。特点是代码简洁,是一种发布订阅设计模式...
https://github.com/hbjycl/event-bus-init.git
C#版本EventBus事件总线实例源码2019
Event Bus是一个发布 / 订阅的事件总线。 Event Bus模式 — 也被称为Message Bus或者发布者/订阅者(publisher/subscriber)模式 — 可以让两个组件相互通信,但是他们之间并不相互知晓。 基于事件总线管理/订阅/...
Android事件框架EventBus使用实例
enentbus_otto实现组件发布订阅模式,极大解偶组件的事件监听
EventBus - Go轻量级事件总线兼容异步
EventBus、Otto、RxBus事件总线使用
android基于livedata实现的事件总线框架,可以根据key来识别特定的通知,优雅的解决eventbus的弊端,不依赖第三方库,更加轻量好用。
C# Event Bus Demo C# 事件总线实例 非常简单的事件总线实例,学习入门的基础
一个事件总线框架用于事件驱动编程
C#版本EventBus事件总线实例源码