編輯:關於Android編程
針對事件提供統一訂閱,發布以達到組件間通信的解決方案。
觀察者模式。
先看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應用內組件通信。
在工作上,我在兩個場景下分別使用過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規定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));
這裡要注意幾點點:
(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在接受事件的方法加上修飾符 at 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());
//...
}
}
深入理解Activity啟動流程(一)–Activity啟動相關類的類圖Activity啟動時的概要交互流程用戶從Launcher程序點擊應用圖標
第二種主界面風格則是以網易新聞、鳳凰新聞以及新推出的新浪博客(閱讀版)為代表,使用ViewPager+Fragment,即ViewPager裡適配器裡放的不是一般的Vie
不少玩家會想到將圖片拷貝到電腦中,然後用PS等工具去標注編輯加工,然在再發送到朋友圈或社交平台。那麼,轉來轉去,是不是也不太方便呢?其實Android手機也
本文將介紹一種通過代碼控制ListView上下滾動的方法。 先上圖: 按下按鈕會觸發ListView滾動或停止。 實現該功能並不難,下面給出主要代碼MainAct