针对事件提供统一订阅,发布以达到组件间通讯的解决方案。java
观察者模式。android
先看EventBus的官方定义:git
Android optimized event bus that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
再看Otto官方定义:github
Otto is an event bus designed to decouple different parts of your application while still allowing them to communicate efficiently.
总之,简化android应用内组件通讯。设计模式
在工做上,我在两个场景下分别使用过Otto和EventBus,一个是下载管理器通知各个相关的Activity当前的进度,一个是设置应用壁纸。
单从使用上看,EventBus > Otto > BroadcastReceiver(固然BroadcastReceiver做为系统内置组件,有一些前二者没有的功能).
EventBus最简洁,Otto最符合Guava EventBus的设计思路, BroadcastReceiver最难使用。
我我的的第一选择是EventBus。app
两大的框架的基本使用都很是简单:
EventBus的基本使用官方参考:https://github.com/greenrobot/EventBus
Otto的基本使用官方参考:http://square.github.io/otto/框架
EventBus规定onEvent方法固定做为订阅者接受事件的方法,应该是参考了“约定优于配置”思想。ide
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; } }
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的背景壁纸 // ... } }
private void downloadWallpapper(String src) { ImageLoader.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(); } }); }
重点就是这句:post
// 在任何地方调用下面的方法,便可动态全局实现壁纸设置功能 EventBus.getDefault().post(new WallpaperEvent(wallpaper));
这里要注意几点点:
(1)Otto使用注解定义订阅/发布者的角色,@Subscribe为订阅者,@Produce为发布者,方法名称就能够自定义了。
(2)Otto为了性能,代码意图清晰,@Subscribe,@Produce方法必须定义在直接的做用类上,而不能定义在基类而被继承。
(3)和EventBus不一样的是,发布者也须要register和unregister,而EventBus的发布者是不须要的。性能
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; } }
public class AppConfig { private static final Bus BUS = new Bus(); public static Bus getInstance() { return BUS; } }
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的背景壁纸 // ... } }
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()); //... } }