1. 程式人生 > >【部落格地址永久遷移到】:http://zhengxiaoyong.me

【部落格地址永久遷移到】:http://zhengxiaoyong.me

顧名思義,AndroidEventBus是一個Android平臺的事件匯流排框架,它簡化了Activity、Fragment、Service等元件之間的互動,很大程度上降低了它們之間的耦合,使我們的程式碼更加簡潔,耦合性更低,提升了我們的程式碼質量。但它能做的卻不僅限於這些。經過定製,它能完成很多有意思的功能,那麼究竟該怎麼做呢?就讓我們一起往下看吧。      

不堪回首的痛

首先,讓我們先來看看這麼一個場景:你是否在開發的過程中遇到過從Activity-A跳轉到Activity-B,然後需要在Activity-B處理完某些工作之後回撥Activity-A中的某個函式,但Activity又不能手動建立物件來設定一個Listener的情況?或者遇到在某個Service中更新Activity或Fragment中的介面等元件之間的互動問題……      

一經思考,你會發現Android中的Activity、Fragment、Service之間的互動是比較麻煩的,可能我們第一想到的是使用廣播接收器來在它們之間進行互動。如上文所說,在Activity-B中發一個廣播,在Activity-A中註冊一個廣播接收器來接收該廣播。但使用廣播接收器稍顯麻煩,如果你要將一個實體類當作資料在元件之間傳遞,那麼該實體類還得實現序列化介面,這個成本實在有點高!如程式碼1所示。

  1. class ActivityA extends Activity {  
  2.         @Override  
  3.         protectedvoid
     onCreate(Bundle savedInstanceState) {  
  4.             super.onCreate(savedInstanceState);             
  5.               // ActivityA中註冊廣播接收器
  6.             registerReceiver(new BroadcastReceiver() {                  
  7.                 @Override  
  8.                 publicvoid onReceive(Context context, Intent intent) {  
  9.                     User person = intent.getParcelableExtra("user") ;  
  10.                 }  
  11.             }, new IntentFilter("my_action")) ;  
  12.         }  
  13.         // ...... 
  14.     }      
  15.     // ActivityB中釋出廣播
  16.     class ActivityB extends Activity {  
  17.         @Override  
  18.         protectedvoid onCreate(Bundle savedInstanceState) {  
  19.             super.onCreate(savedInstanceState);              
  20.             // 釋出廣播
  21.             Intent intent  = new Intent("my_    action");  
  22.             intent.putExtra("user", new User("mr.simple")) ;  
  23.             sendBroadcast(intent);  
  24.         }  
  25.         // ...... 
  26.     }     
  27.     // 實體類需要實現序列化
  28.     class User implements Parcelable {  
  29.         String name ;  
  30.         public User(String aName) {  
  31.             name = aName ;  
  32.         }         
  33.        // 程式碼省略
  34.         @Override  
  35.         publicvoid writeToParcel(Parcel dest, int flags) {  
  36.             dest.writeString(name);  
  37.         }  
  38.     }  

程式碼1

是不是有很麻煩的感覺?我們再來看一個示例,在開發過程中,我們經常要在子執行緒中做一些耗時操作,然後將結果更新到UI執行緒,除了AsyncTask之外,Thread加Handler是我們經常用的手段。如程式碼2所示。

  1. class MyActivity extends Activity {          
  2.         Handler mHandler = new Handler () {  
  3.             publicvoid handleMessage(android.os.Message msg) {  
  4.                 if ( msg.what == 1 ) {  
  5.                     User user = (User)msg.obj ;  
  6.                     // do sth
  7.                 }  
  8.             };  
  9.         } ;         
  10.         @Override  
  11.         protectedvoid onCreate(Bundle savedInstanceState) {  
  12.             super.onCreate(savedInstanceState);  
  13.             // code ......           
  14.             new Thread(  
  15.                 new Runnable() {  
  16.                     publicvoid run() {  
  17.                         // do sth
  18.                         User newUser = new User("simple") ;  
  19.                         Message msg = mHandler.obtainMessage() ;  
  20.                         msg.what = 1 ;  
  21.                         msg.obj = newUser ;  
  22.                         mHandler.sendMessage(msg) ;  
  23.                     }  
  24.             }).start();  
  25.         }  
  26.     }  

程式碼2

是不是依然相當麻煩?當然你也可以使用AsyncTask來簡化操作,但AsyncTask的幾個泛型引數讓你的程式碼看起來並不那麼簡潔,因此GitHub上出現了TinyTask、SimpleTask這些開源庫來簡化AsyncTask的使用。而這些,使用AndroidEventBus都可以很好地解決!

下面就讓我們來領悟一下AndroidEventBus的強大魅力吧。

初見AndroidEventBus

使用AndroidEventBus簡單概括只有三個步驟:

  • 將物件註冊到AndroidEventBus中;
  • 使用@Subcriber標註訂閱函式(只能有一個引數);
  • 通過post函式釋出事件。

接下來就是註冊訂閱物件,如程式碼3所示。

  1. publicclass MainActivity extends Activity {  
  2.     @Override  
  3.     protectedvoid onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_main);  
  6.         // 將物件註冊到事件匯流排中, ****** 注意要在onDestory中進行登出 ****
  7.         EventBus.getDefault().register(this);  
  8.     }  
  9.     @Override  
  10.     protectedvoid onDestroy() {  
  11.         super.onDestroy();  
  12.         // ****** 不要忘了進行登出 ****
  13.         EventBus.getDefault().unregister(this);  
  14.     }      
  15.     // 程式碼省略
  16. }      

程式碼3

在onCreate中註冊之後,MainActivity就可以新增訂閱函式來接收訊息了。需要注意的是在onDestory中需要將MainActivity從事件匯流排中登出。通過AndroidEventBus你可以去除Activity、Fragment、Service等元件的回撥,減少了耦合,簡化了程式碼。 

事件訂閱函式

事件訂閱需要使用@Subscriber註解進行標識,且訂閱函式的引數必須為一個。事件匯流排憑藉引數型別和@Subscriber註解的tag值來標識訂閱函式的唯一性。當用戶釋出事件時,匯流排庫會根據事件型別和tag來查詢符合要求的訂閱函式,並且將這些訂閱函式執行在對應的執行緒中。我們先來看看程式碼4的訂閱函式示例。

  1. publicclass MainActivity extends Activity {  
  2.     // 程式碼省略 
  3.     @Subcriber(tag = "csuicide")  
  4.     privatevoid csuicideMyself(String msg) {  
  5.         // do sth
  6.         finish();  
  7.     }  
  8.     @Subcriber(mode = ThreadMode.MAIN)  
  9.     privatevoid toastMsgFromEvent(String msg) {  
  10.         // do sth
  11.     }  
  12.     @Subcriber(tag = "async", mode = ThreadMode.ASYNC)  
  13.     privatevoid executeAsync(final String msg) {  
  14.        // do sth
  15.     }  
  16.     // 程式碼省略
  17. }      

程式碼4

在程式碼4中,我們為MainActivity添加了以下三個訂閱函式: 

  • csuicideMyself:該訂閱函式執行在主執行緒,接收事件的型別為String,tag為csuicide。當用戶釋出一個事件型別為String,且tag為csuicide的事件時將會觸發該方法。
  • toastMsgFromEvent:該訂閱函式也是執行在主執行緒,事件型別為String,且tag為預設。當用戶釋出一個事件型別為String,且tag為預設的事件時將會觸發該方法。
  • executeAsync:該訂閱函式也是執行在一個非同步執行緒,事件型別為String,且tag為async。當用戶釋出一個事件型別為String,且tag為async的事件時將會觸發該方法。

從上述的描述中我們可以知道,事件接收函式主要有兩個約束:事件型別和tag(類似於Intent中的Action)。新增tag是因為在事件型別一樣時,如果投遞一個訊息,那麼單純以事件型別(例如String)作為投遞依據,那麼多個引數為String的訂閱函式將會被觸發,這極大地降低了靈活性。

釋出事件

引數1為事件型別,無tag:EventBus.getDefault().post(這是一個執行在非同步執行緒的事件);引數2為tag,tag的型別為String,類似Intent的Action:EventBus.getDefault().post(這是一個執行在非同步執行緒的事件:“async”)。

釋出事件時可以構造任意型別的事件,如果沒有tag則該引數可以省略。釋出事件後,AndroidEventBus會根據事件型別和tag到已註冊的訂閱物件中查詢符合要求的訂閱函式,例如投遞的第二個事件型別為String、tag為async,那麼在MainActivity中符合要求的訂閱函式就是:

  1. 相關推薦

    部落地址永久遷移http://zhengxiaoyong.me

    顧名思義,AndroidEventBus是一個Android平臺的事件匯流排框架,它簡化了Activity、Fragment、Service等元件之間的互動,很大程度上降低了它們之間的耦合,使我們的程式碼更加簡潔,耦合性更低,提升了我們的程式碼質量。但它能做的卻不僅限

    部落搬家舊文leetcode 771. Jewels and Stones

      今天開通了部落格園 ,之前的部落格就不用了。之後再陸陸續續把之前的博文重新放到這裡來。有標題這個tag的都是搬運的舊部落格的文章。希望在這裡是個新的開始,嘻嘻。      import java.util.Scanner; class Solution { public

    部落搬家舊文leetcode515. Find Largest Value in Each Tree Row

      注:這是我春招找實習的時候筆試某公司的原題,當時還傻傻的不太會做。 //廣度優先搜尋就可以實現二叉樹每一層的遍歷,通常都用佇列來實現。佇列儲存未被檢測的結點,結點按寬度優先的次序被訪問和進出佇列。 /** * Definition for a binary tree node. * pub

    nzf_001的專欄nzf_001的專欄nzf_001的專欄nzf_001的專欄nzf_001的專欄歡迎加入部落 QQ 群631873947,加群請註明 CSDN 部落地址。歡迎加入部落 QQ 群631873947,加群請註明 CSDN 部落地址

    歡迎加入部落格 QQ 群:631873947,加群請註明 CSDN 部落格地址。歡迎加入部落格 QQ 群:631873947,加群請註明 CSDN 部落格地址。歡迎加入部落格 QQ 群:631873947,加群...

    不積跬步,無以至千里個人部落地址https://lewky.cn

    /*** * --------------攻城獅-------------- * ,%%%%%%%%, * ,%%/\%%%%/\%% * ,%%%\c "" J/%%% * %. %%%%/

    部落之星分享是一種美德,年輕就該努力

      首先感謝CSDN給我這次機會參加2013部落格之星候選人,記得兩年前剛開始在CSDN寫部落格的時候,那時候還擔心寫的東西太爛,被別人罵。現在想想當時的想法真是多餘的。兩年來,我從一個對程式設計幾乎算不上入門的傻小子,到現在能簡單的寫一些有用的程式碼。回往這兩年,真的感謝以前那個

    去除CSDN論壇部落所有廣告的方法(非會員or非專家/版主 也可使用哦)

    一、置頂 你是否已經被CSDN繁雜的廣告弄的煩擾不堪? 你是否已經被CSDN 推薦的垃圾部落格連結弄的心情暴躁? 你是否已經被CSDN 部落格底部的部落格推薦連結弄的無法安心學習? 下面我就教大家怎麼去除這繁雜的廣告,還論壇一片清淨!!! 二、概述 本人在CSDN也算是玩的很久的了

    部落園2018總結帖21天,在Github上獲取 6300 star

    大家好,我是程式設計師小吳。12月初我在GitHub上上傳了一個倉庫,到現在為止獲取了 6300 star,下面和大家聊聊關於專案啟動的初衷、面臨的一些困難和未來的計劃。 「LeetcodeAnimation」的萌芽? 在刷Leetcode的過程中,遇到很多有意思和有難度的題目,有時候自己能做出來,有時候

    部落搬往 http://begtostudy.cnblogs.com請不要在這個部落發表評論,抗議CSDN隨意刪除我部落元件和博文,廢棄部落不再回復!

    Dr. Ing. 白途思(Begtostudy) 微訊號:Begtostudy QQ:370566617 Email: [email protected] 點選這裡給我發郵件 工作單位:上海航天技術研究院 身份:上海交通大學 工學博士 校內名片

    部落搬家CSDN/部落園等搬到wordpress中

    更新: 因為已經過去很長時間了,本人也一直沒時間實際去看評論區的問題,可能次外掛現在並不好用了 以下原文: 個人部落格搞的差不多了,就準備把現在csdn中的博文都搬過去。複製貼上顯然不行(畢竟還是寫了

    個人部落地址http://oldchen.iwulai.com

    直接上程式碼:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

    部落地址blog.songchunmin.com

    0. Core Image 作為設計和體驗方面的領導者,蘋果自己對圖片效果和圖片處理的支援一定是非常好的,在iOS平臺上,5.0之後就出現了Core Image的API。Core Image的API被放在CoreImage.framework庫中。 在iOS和OS

    全網最全的部落美化系列教程文章總目錄

    前言   很多熱心的園友叫我出一部部落格美化系列的教程,都覺得我部落格做的很漂亮?之前我也有寫過部落格美化教程,不過好像一篇文章的篇幅有點過長了,為了方便園友的檢視,我決定重新出一套部落格美化教程,把原有的功能進行細化,每種功能單獨以一篇文章的形式發表,在保留原有功能的基礎上,會持續更新探索一些好玩好看的新

    全網最全的部落美化系列教程03.給部落新增一隻萌萌噠的小倉鼠

    全網最全的部落格美化系列教程相關文章目錄 【全網最全的部落格美化系列教程】09.新增"擴大/縮小瀏覽區域大小" 按鈕 【全網最全的部落格美化系列教程】10.小火箭置頂特效的實現 【全網最全的部落格美化系列教程】11.滑鼠點選愛心特效的實現 【全網最全的部落格美化系列教程

    全網最全的部落美化系列教程08.自定義位址列Logo

    全網最全的部落格美化系列教程相關文章目錄 【全網最全的部落格美化系列教程】09.新增"擴大/縮小瀏覽區域大小" 按鈕 【全網最全的部落格美化系列教程】10.小火箭置頂特效的實現 【全網最全的部落格美化系列教程】11.滑鼠點選愛心特效的實現 【全網最全的部落格美化系列教程

    部落地址www.yizhen-blog.com 歡迎交流

    在學習深度學習相關知識,無疑都是從神經網路開始入手,在神經網路對引數的學習演算法bp演算法,接觸了很多次,每一次查詢資料學習,都有著似懂非懂的感覺,這次趁著思路比較清楚,也為了能夠讓一些像我一樣疲於各

    CSDN 官方部落(歡迎加入部落 QQ 群374041348,加群請註明 CSDN 部落地址。)

    這些年,我們讀過的技術經典圖書 極限程式設計創始人Kent Beck說過“每個有思想的軟體開發人員,書架上都應該有這樣一本書”,你的書架上又都有些什麼書呢?CSDN眾博主們用一起分享了自己學程式設計過程中讀過的技術經典。

    部落地址https://my.oschina.net/hebaodan/blog/

    思路: 按代價大小從高到低排序,代價一樣則最後期限早的在前, 按排序順序遍歷,事件安排進終止日期那一天,如果該日期已被那排,就在往前推, 如果最後安排不下,就扣分。 #include<iostream> #include<algorithm> us

    不積跬步,無以至千里(個人部落地址https://lewky.cn)

    /*** * --------------攻城獅-------------- * ,%%%%%%%%, * ,%%/\%%%%/\%% * ,%%%\c "" J/%%% * %. %%%%/

    ssm個人部落專案實戰01SSM環境搭建

    前言 今天開始就做一個個人部落格實戰專案了,首先就專案環境的搭建,萬丈高樓平地起。這篇 部落格主要講解基於maven的ssm專案整合。 1、ssm系統架構 整合步驟 第一步:   MyBatis和Spring整合,通過Spring管理mapp