Android學習系列(43)--使用事件匯流排架構EventBus和Otto

來源:互聯網
上載者:User

標籤:android   android開發   

事件匯流排架構

針對事件提供統一訂閱,發布以達到組件間通訊的解決方案。

原理

觀察者模式。

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方法固定作為訂閱者接受事件的方法,應該是參考了“約定優於配置”思想。

  1. 定義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;}}
  2. 定義訂閱者,最重要的是onEvent方法

    public class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    EventBus.getDefault().register(this);    initWallpaper();}@Overrideprotected 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的背景壁紙    // ...}}
  3. 通過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的發行者是不需要的。

  1. 定義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;}}
  2. 避免浪費,相對於EventBus.getDefault(), Otto需要自己實現單例。

    public class AppConfig {private static final Bus BUS = new Bus();public static Bus getInstance() {    return BUS;}}
  3. 定義訂閱者,在接受事件的方法加上修飾符@Subscribe在接受事件的方法加上修飾符 at Subscribe

    public class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    AppConfig.getBusInstance().register(this);    initWallpaper();}@Overrideprotected 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的背景壁紙    // ...}}
  4. 定義發行者,通過post()方法在任何地方發布訊息了

    public class WallpaperActivity extends BaseActivity {private Drawable wallpaperDrawable;//這裡同時也要更新自己壁紙,所以顯示定義@Subscribe的方法@Subscribepublic void onWallpaperUpdate(WallpaperEvent wallpaperEvent) {    super.onWallpaperUpdate(wallpaperEvent);}@Producepublic WallpaperEvent publishWallPaper() {    return new WallpaperEvent(wallpaperDrawable);}private void downloadWallpapper(String src) {    //...    //通知所有@Subscribe匹配WallpaperEvent參數的方法執行    AppConfig.getBusInstance().post(publishWallPaper());    //...}}
小結
  1. 使用設計模式的思想解決問題,這才是設計模式的真正價值。
  2. 這兩個android事件匯流排架構提供了一種更靈活更強大而又更加完美解耦的解決方案,在很多場合,從開發效率,執行效能和設計思路上都要優於BroadcastReceiver,值得學習使用。

其他精彩文章文章

android學習筆記(41)android選項菜單和子功能表(SubMenu )android學習筆記(40)Notification的功能與用法android學習筆記(42)android使用監聽器來監聽菜單事件android學習筆記(43)android建立單選菜單和複選菜單 jQuery教程(12)-ajax操作之基於請求載入資料 jQuery教程(13)-ajax操作之追加 HTML

更多關於android開發文章

Android學習系列(43)--使用事件匯流排架構EventBus和Otto

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.