Android實際開發常用框架總結

Android實際開發常用框架總結

一、進行網絡請求的常用框架及其用法
1、OKHTTP的實際開發中的用法
2、Volley的實際開發中的用法

二、實際開發中進行圖片下載以及緩存的框架
1、神奇的Picasso 框架
2、Android Universal Image Loader
3、Glide最火圖片加載開源框架加載Gif資源圖到Android ImageView中
4、Fresco讓圖片的漸進式呈現的強大框架
5、Picasso, ImageLoader, Fresco, Glide優劣

三、實際開發中對View對象注入以及事件綁定的框架
1、ButterKnife(黃油刀)的用法
2、Dagger的用法

四、2016年實際開發進行JSON解析的最火框架
1、FastJson最全面的Json解析框架
2、Gson一句代碼搞定Json的解析

五、發佈 / 訂閱的事件總線
(一) Otto與EventBus
1、Bus實例化
2、註冊和解綁Bus
3、消息的發佈
4、消息的訂閱
5、消息的produce

2016年Android實際開發常用框架總結
一、進行網絡請求的常用框架及其用法
1、OKHTTP的實際開發中的用法
Android系統提供了兩種HTTP通訊類HttpURLConnection和HttpClient,Android6.0後,HttpClient就被google公司給廢棄了。儘管Google在大部分安卓版本中推薦使用HttpURLConnectin,但是這個類相比HttpClient實在是太難用,太弱爆了。
OkHttp是一個相對成熟的解決方案,據說Android4.4的源碼中可以看到HttpURLConnection已經替換成OkHttp實現了。所以我們更有理由相信OkHttp的強大。
使用範圍:OkHttp支持Android2.3及其以上版本。對於Java,JDK1.7以上。
基本使用(GET請求):
這裏寫圖片描述

總結:Request是OkHttp中訪問的請求,Builder是輔助類,Response就是OkHttp的響應。

POST提交鍵值對請求:
很多時候我們會需要通過POST方式把鍵值對數據傳送到服務器。OkHttp提供了很多方便的方式來做這件事情。
這裏寫圖片描述

總結:通過上面的例子我們可以發現,OkHttp在很多時候使用都是很方便的,而且很多代碼也有重複,因此特地整理了下面的工具類。 注意:
1、OkHttp官方文檔並不建議我們創建多個OkHttpClient,因此全局使用一個。 如果有需要,可以使用clone方法,再進行自定義。
2、enqueue爲OkHttp提供的異步方法。
OkHttpUtil類當中的方法:
① 不會開啓異步線程方法:
public static Response execute(Request request);
② 開啓異步線程訪問網絡:
public static void enqueue(Request request, Callback responseCallback);
③ 開啓異步線程訪問網絡,且不在意返回結果(實現空callback):
public static void enqueue(Request request);
④ 使用了HttpClient的API,只是爲了方便:
Public static String formatParams(Listparams);
⑤ 爲HttpGet的Url方便的添加多個name和Value參數:
Public static StringattachHttpGetParams(Stringurl,List params);
⑥ 位HttpGet的url方便的添加一個name和value參數:
Public static String attachHttpGetParam(String url, String name, String value);

2、Volley的實際開發中的用法
Volley常見用法介紹
    我們平時在開發Android應用的時候不可避免地都需要用到網絡技術,而多數情況下應用程序都會使用HTTP協議來發送和接收網絡數據。Android系統中主要提供了兩種方式來進行HTTP通信,HttpURLConnection和HttpClient,幾乎在任何項目的代碼中我們都能看到這兩個類的身影,使用率非常高。
不過HttpURLConnection和HttpClient的用法還是稍微有些複雜的,如果不進行適當封裝的話,很容易就會寫出不少重複代碼。於是乎,一些Android網絡通信框架也就應運而生,比如說AsyncHttpClient,它把HTTP所有的通信細節全部封裝在了內部,我們只需要簡單調用幾行代碼就可以完成通信操作了。再比如Universal-Image-Loader,它使得在界面上顯示網絡圖片的操作變得極度簡單,開發者不用關心如何從網絡上獲取圖片,也不用關心開啓線程、回收圖片資源等細節,Universal-Image-Loader已經把一切都做好了。
    Android開發團隊也是意識到了有必要將HTTP的通信操作再進行簡單化,於是在2013年Google I/O大會上推出了一個新的網絡通信框架——Volley。Volley可是說是把AsyncHttpClient和Universal-Image-Loader的優點集於了一身,既可以像AsyncHttpClient一樣非常簡單地進行HTTP通信,也可以像Universal-Image-Loader一樣輕鬆加載網絡上的圖片。除了簡單易用之外,Volley在性能方面也進行了大幅度的調整,它的設計目標就是非常適合去進行數據量不大,但通信頻繁的網絡操作,而對於大數據量的網絡操作,比如說下載文件等,Volley的表現就會非常糟糕。
    下圖所示的這些應用都是屬於數據量不大,但網絡通信頻繁的,因此非常適合使用Volley。
這裏寫圖片描述
(1)下載Volley
介紹了這麼多理論的東西,下面我們就準備開始進行實戰了,首先需要將Volley的jar包準備好,如果你的電腦上裝有Git,可以使用如下命令下載Volley的源碼:
git clone https://android.googlesource.com/platform/frameworks/volley
下載完成後將它導入到你的Eclipse工程裏,然後再導出一個jar包就可以了。如果你的電腦上沒有Git,那麼也可以直接使用我導出好的jar包,下載地址是:http://www.kwstu.com/ResourcesView/kwstu_201441183330928
新建一個Android項目,將volley.jar文件複製到libs目錄下,這樣準備工作就算是做好了。

(2)StringRequest的用法
    前面已經說過,Volley的用法非常簡單,那麼我們就從最基本的HTTP通信開始學習吧,即發起一條HTTP請求,然後接收HTTP響應。首先需要獲取到一個RequestQueue對象,可以調用如下方法獲取到:
RequestQueue mQueue = Volley.newRequestQueue(context);
注意這裏拿到的RequestQueue是一個請求隊列對象,它可以緩存所有的HTTP請求,然後按照一定的算法併發地發出這些請求。RequestQueue內部的設計就是非常合適高併發的,因此我們不必爲每一次HTTP請求都創建一個RequestQueue對象,這是非常浪費資源的,基本上在每一個需要和網絡交互的Activity中創建一個RequestQueue對象就足夠了。
    接下來爲了要發出一條HTTP請求,我們還需要創建一個StringRequest對象,如下所示:
這裏寫圖片描述
可以看到,這裏new出了一個StringRequest對象,StringRequest的構造函數需要傳入三個參數,第一個參數就是目標服務器的URL地址,第二個參數是服務器響應成功的回調,第三個參數是服務器響應失敗的回調。其中,目標服務器地址我們填寫的是百度的首頁,然後在響應成功的回調裏打印出服務器返回的內容,在響應失敗的回調裏打印出失敗的詳細信息。
    最後,將這個StringRequest對象添加到RequestQueue裏面就可以了,如下所示:
mQueue.add(stringRequest);
    另外,由於Volley是要訪問網絡的,因此不要忘記在你的AndroidManifest.xml中添加如下權限:
< uses-permission android:name=”android.permission.INTERNET” />
好了,就是這麼簡單,如果你現在運行一下程序,併發出這樣一條HTTP請求,就會看到LogCat中會打印出如下圖所示的數據。
這裏寫圖片描述
    沒錯,百度返回給我們的就是這樣一長串的HTML代碼,雖然我們看起來會有些吃力,但是瀏覽器卻可以輕鬆地對這段HTML代碼進行解析,然後將百度的首頁展現出來。這樣的話,一個最基本的HTTP發送與響應的功能就完成了。你會發現根本還沒寫幾行代碼就輕易實現了這個功能,主要就是進行了以下三步操作:
1. 創建一個RequestQueue對象。
2. 創建一個StringRequest對象。
3. 將StringRequest對象添加到RequestQueue裏面。
    不過大家都知道,HTTP的請求類型通常有兩種,GET和POST,剛纔我們使用的明顯是一個GET請求,那麼如果想要發出一條POST請求應該怎麼做呢?StringRequest中還提供了另外一種四個參數的構造函數,其中第一個參數就是指定請求類型的,我們可以使用如下方式進行指定:
[java] view plaincopy
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener);
可是這只是指定了HTTP請求方式是POST,那麼我們要提交給服務器的參數又該怎麼設置呢?很遺憾,StringRequest中並沒有提供設置POST參數的方法,但是當發出POST請求的時候,Volley會嘗試調用StringRequest的父類——Request中的getParams()方法來獲取POST參數,那麼解決方法自然也就有了,我們只需要在StringRequest的匿名類中重寫getParams()方法,在這裏設置POST參數就可以了,代碼如下所示:
這裏寫圖片描述
    你可能會說,每次都這樣用起來豈不是很累?連個設置POST參數的方法都沒有。但是不要忘記,Volley是開源的,只要你願意,你可以自由地在裏面添加和修改任何的方法,輕鬆就能定製出一個屬於你自己的Volley版本。

(3)JsonRequest的用法
    學完了最基本的StringRequest的用法,我們再來進階學習一下JsonRequest的用法。類似於StringRequest,JsonRequest也是繼承自Request類的,不過由於JsonRequest是一個抽象類,因此我們無法直接創建它的實例,那麼只能從它的子類入手了。JsonRequest有兩個直接的子類,JsonObjectRequest和JsonArrayRequest,從名字上你應該能就看出它們的區別了吧?一個是用於請求一段JSON數據的,一個是用於請求一段JSON數組的。至於它們的用法也基本上沒有什麼特殊之處,先new出一個JsonObjectRequest對象,如下所示:
這裏寫圖片描述
    可以看到,這裏我們填寫的URL地址是http://m.weather.com.cn/data/101010100.html,這是中國天氣網提供的一個查詢天氣信息的接口,響應的數據就是以JSON格式返回的,然後我們在onResponse()方法中將返回的數據打印出來。
    最後再將這個JsonObjectRequest對象添加到RequestQueue裏就可以了,如下所示:
mQueue.add(jsonObjectRequest);
這樣當HTTP通信完成之後,服務器響應的天氣信息就會回調到onResponse()方法中,並打印出來。現在運行一下程序,發出這樣一條HTTP請求,就會看到LogCat中會打印出如下圖所示的數據。
這裏寫圖片描述

    由此可以看出,服務器返回給我們的數據確實是JSON格式的,並且onResponse()方法中攜帶的參數也正是一個JSONObject對象,之後只需要從JSONObject對象取出我們想要得到的那部分數據就可以了。
    你應該發現了吧,JsonObjectRequest的用法和StringRequest的用法基本上是完全一樣的,Volley的易用之處也在這裏體現出來了,會了一種就可以讓你舉一反三,因此關於JsonArrayRequest的用法相信已經不需要我再去講解了吧。

(4)Volley的優缺點
優點: Volley的優點在於請求隊列的管理, 適合小而頻繁的請求, 如果app比較小, 網絡請求要求不高的情況下可以使用volley, 通常情況下是要結合其他框架一起來使用, 比如volley+okhttp.

缺點: 下載大文件性能不佳, 不支持大文件上傳

二、實際開發中進行圖片下載以及緩存的框架
1、神奇的Picasso 框架
    在Android中開發,常需要從遠程獲取圖片並顯示在客戶端,當然我們可以使用原生HttpURLConnection和AsyncTask等操作來完成,但並不推薦,因爲這樣不僅需要我們編寫大量的代碼, 還需要處理緩存和下載管理等,最好自己封裝成庫或者採用第三方庫;
使用HttpUrlConnection和AsyncTask實現遠程圖片下載:
使用HttpUrlConnection和AsyncTask獲取遠程圖片,需要以下幾步:
1、HttpUrlConnection connection = url.openConnection();
2、InputStream in = connection.getInputStream();
3、Bitmap bitmap = BitmapFactory.decodeStream(in);
4、imageView.setBitmap(bitmap);
我們知道在主線程中是無法執行聯網操作的,所以需要AsyncTask,將耗時操作運行在後臺線程中。

Picasso的基本使用:
將Picasso添加進項目後,要使用它非常簡單,只需要一行代碼就能搞定:
Picasso.with(context).load(imageUrl).into(imageView);
1、自動將圖像緩存在本地;
2、通過圖片壓縮轉換以減少內存消耗;
3、自動處理了ImageView的回收,即自動取消不在視野範圍內的ImageView視圖資源的加載;
適配器:
適配器自動發現和重用以前取消的下載:
這裏寫圖片描述
圖像格式轉換:
很多時候需要將圖片進行格式轉換或者剪切以節省內存或者達到我麼的佈局效果:
裁剪大小方法:Picasso.with(context).load(imageUrl).resize(50, 50).centerCrop().info(imageView);
自定義格式轉換:
爲了實現更多你想要圖片轉換的效果,你可以自己實現一個實現了Transformation接口的類,然後將其對象傳遞給transform()方法:
這裏寫圖片描述
佔位符圖片:
所謂的佔位符圖像即當圖片未正常顯示時默認的圖片,通過placeholder()設置,Picasso也支持設置圖片顯示錯誤時顯示的默認圖片,通過error()設Picasso.with(context).load(imageUrl).placeholder(R.drawable.image_placeholder).error(R.drawable.image_error_placeholder).into(imageView);
載入本地資源:
除了通過網絡下載圖片,Picasso也可以載入本地圖片資源:
Picasso.with(context).load(R.drawable.icon).into(imageView);
Picasso.with(context).load(“file:///android_asset/Android.png”).into(imageView);
Picasso.with(context).load(new File(…)).into(imageView);

調試:
爲了方便調試,你可以通過調試Picasso的setIndicatiorEnabled(true);可以讓不同來源的圖片顯示一個不同的色彩標記

2、Android Universal Image Loader
    實際項目開發中ImageLoader的使用率非常的高,用法多樣性很大,由於篇幅問題,詳情請猛戳下面鏈接:
http://note.youdao.com/share/?id=7601c6850df29dea288734677fd5a56c&type=note

3、Glide最火圖片加載開源框架加載Gif資源圖到Android ImageView中
    通常Android的ImageView不能加載Gif圖片,如不做任何處理,那麼加載到ImageView中的Gif只顯示第一幀。網上給出很多解決方案,也有不少開源框架定製專屬的Gif View用於加載Gif圖,這些解決方案基本上大多數是藉助Android的Movie,把Gif圖片資源作爲流,解析成Android Movie顯示,這些定製的基本思想就是先檢測該圖片資源是否是Gif圖,若是,則按照Android Movie解析之。
    有一個Android Glide開源框架,本身在圖片加載和緩存方面做的比較優秀,我之前已寫了一篇文章專門介紹如何在自己的項目中具體使用Android Glide庫(該文章的鏈接地址:http://blog.csdn.net/zhangphil/article/details/45535693 ),同時,Android Glide加載Gif圖片也很方便,把需要加載的gif圖放到drawable目錄下,然後就和普通的Andriod ImageView設置一個圖片資源R.drawanle.xxx一模一樣,很簡單。或者從網路URL加載一個圖片,開發者不用關心這個圖片資源是否是gif還是其他jpg還是png等等格式,直接將其當作一個普通的圖片加載之即可,至於該圖片資源格式的判斷處理及繪製,則有Android Glide全部代勞。
現舉例:
這裏寫圖片描述
其中,R.drawable.loading是加載了drawable目錄下的loading.gif圖:
這裏寫圖片描述

4、Fresco讓圖片的漸進式呈現的強大框架
    Fresco 是一個強大的圖片加載組件。Fresco 中設計有一個叫做 image pipeline 的模塊。它負責從網絡,從本地文件系統,本地資源加載圖片。爲了最大限度節省空間和CPU時間,它含有3級緩存設計(2級內存,1級文件)。
Fresco 中設計有一個叫做 Drawees 模塊,方便地顯示loading圖,當圖片不再顯示在屏幕上時,及時地釋放內存和空間佔用。
Fresco 支持 Android2.3(API level 9) 及其以上系統。
特性
內存管理
解壓後的圖片,即Android中的Bitmap,佔用大量的內存。大的內存佔用勢必引發更加頻繁的GC。在5.0以下,GC將會顯著地引發界面卡頓。
在5.0以下系統,Fresco將圖片放到一個特別的內存區域。當然,在圖片不顯示的時候,佔用的內存會自動被釋放。這會使得APP更加流暢,減少因圖片內存佔用而引發的OOM。
Fresco 在低端機器上表現一樣出色,你再也不用因圖片內存佔用而思前想後。
圖片的漸進式呈現
漸進式的JPEG圖片格式已經流行數年了,漸進式圖片格式先呈現大致的圖片輪廓,然後隨着圖片下載的繼續,呈現逐漸清晰的圖片,這對於移動設備,尤其是慢網絡有極大的利好,可帶來更好的用戶體驗。
Android 本身的圖片庫不支持此格式,但是Fresco支持。使用時,和往常一樣,僅僅需要提供一個圖片的URI即可,剩下的事情,Fresco會處理。
Gif圖和WebP格式
是的,支持加載Gif圖,支持WebP格式。
圖像的呈現
Fresco 的 Drawees 設計,帶來一些有用的特性:
自定義居中焦點(對人臉等圖片顯示非常有幫助)
圓角圖,當然圓圈也行。
下載失敗之後,點擊重現下載
自定義佔位圖,自定義overlay, 或者進度條
指定用戶按壓時的overlay
圖像的加載
Fresco 的 image pipeline 設計,允許用戶在多方面控制圖片的加載:
爲同一個圖片指定不同的遠程路徑,或者使用已經存在本地緩存中的圖片
先顯示一個低解析度的圖片,等高清圖下載完之後再顯示高清圖
加載完成回調通知
對於本地圖,如有EXIF縮略圖,在大圖加載完成之前,可先顯示縮略圖
縮放或者旋轉圖片
處理已下載的圖片
WebP 支持

5、Picasso, ImageLoader, Fresco, Glide優劣
首先看Fresco, 它的優點是其他幾個框架沒有的, 或者說是其他幾個框架的短板.
Fresco:
優點:
 圖片存儲在安卓系統的匿名共享內存, 而不是虛擬機的堆內存中, 圖片的中間緩衝數據也存放在本地堆內存, 所以, 應用程序有更多的內存使用, 不會因爲圖片加載而導致oom, 同時也減少垃圾回收器頻繁調用回收Bitmap導致的界面卡頓, 性能更高.
 漸進式加載JPEG圖片, 支持圖片從模糊到清晰加載
 圖片可以以任意的中心點顯示在ImageView, 而不僅僅是圖片的中心.
 JPEG圖片改變大小也是在native進行的, 不是在虛擬機的堆內存, 同樣減少OOM

缺點:
 框架較大, 影響Apk體積
 使用較繁瑣

ImageLoader, Picasso, Glide: 這三者實現機制都差不多
ImageLoader:
    比較老的框架, 穩定, 加載速度適中, 缺點在於不支持GIF圖片加載, 使用稍微繁瑣, 並且緩存機制沒有和http的緩存很好的結合, 完全是自己的一套緩存機制.
Picasso:
    使用方便, 一行代碼完成加載圖片並顯示, 框架體積小,
缺點在於不支持GIF, 並且它可能是想讓服務器去處理圖片的縮放, 它緩存的圖片是未縮放的, 並且默認使用ARGB_8888格式緩存圖片, 緩存體積大.
Glide:
    可以說是Picasso的升級版, 有Picasso的優點, 並且支持GIF圖片加載顯示, 圖片緩存也會自動縮放, 默認使用RGB_565格式緩存圖片, 是Picasso緩存體積的一半.

三、實際開發中對View對象注入以及事件綁定的框架
1、ButterKnife(黃油刀)的用法
優勢:
1.強大的View綁定和Click事件處理功能,簡化代碼,提升開發效率
2.方便的處理Adapter裏的ViewHolder綁定問題
3.運行時不會影響APP效率,使用配置方便
4.代碼清晰,可讀性強

使用總結:
1. Activity ButterKnife.bind(this);必須在setContentView();之後,且父類bind綁定後,子類不需要再bind
2. Fragment ButterKnife.bind(this, mRootView);
3. 屬性佈局不能用private or static 修飾,否則會報錯
4. setContentView()不能通過註解實現。(其他的有些註解框架可以)

官網 http://jakewharton.github.io/butterknife/
使用步驟:
一.導入ButterKnife jar包:
1)如果你是Eclipse,可以去官網下載jar包
2)如果你是AndroidStudio可以直接 File->Project Structure->Dependencies->Library dependency 搜索 butterknife即可,第一個就是
3)當然也可以用maven和gradle配置

注:官網和github也有對應的引用步驟。

二.常見使用方法:
1)由於每次都要在Activity中的onCreate綁定Activity,所以個人建議寫一個BaseActivity完成綁定,子類繼承即可
注:ButterKnife.bind(this);綁定Activity 必須在setContentView之後:
實現如下(FragmentActivity 實現一樣):
這裏寫圖片描述
2)綁定fragment
這裏寫圖片描述
3)綁定view
@Bind(R.id.hello_world)
TextView mHelloWorldTextView;
@Bind(R.id.app_name)
TextView mAppNameTextView;//view
4)綁定資源
@BindString(R.string.app_name)
String appName;//sting
@BindColor(R.color.red)
int textColor;//顏色
@BindDrawable(R.mipmap.ic_launcher)
Drawable drawable;//drawble
@Bind(R.id.imageview)
ImageView mImageView;
@Bind(R.id.checkbox)
CheckBox mCheckBox;
@BindDrawable(R.drawable.selector_image)
Drawable selector;

2、Dagger的用法
Dagger的用法詳情,請再次猛戳下面鏈接
http://note.youdao.com/share/?id=2c3e8e32150ced0c354ce59e44cd6824&type=note

四、2016年實際開發進行JSON解析的最火框架
1、FastJson最全面的Json解析框架
FastJson使用詳解
一、阿里巴巴FastJson是一個Json處理工具包,包括“序列化”和“反序列化”兩部分,它具備如下特徵:
速度最快,測試表明,fastjson具有極快的性能,超越任其他的Java Json parser。包括自稱最快的JackJson;
功能強大,完全支持Java Bean、集合、Map、日期、Enum,支持範型,支持自省;無依賴,能夠直接運行在Java SE 5.0以上版本;支持Android;開源 (Apache 2.0)
Fastjson API入口類是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON類上的靜態方法直接完成。
這裏寫圖片描述

FastJson解析JSON步驟
A、服務器端將數據轉換成json字符串
首先、服務器端項目要導入阿里巴巴的fastjson的jar包至builtPath路徑下(這些可以到fastjson官網下載:http://code.alibabatech.com/wiki/display/FastJSON/Home-zh
然後將數據轉爲json字符串,核心函數是:
public static String createJsonString(Object value)
{
String alibabaJson = JSON.toJSONString(value);
return alibabaJson;
}

B、客戶端將json字符串轉換爲相應的javaBean
首先客戶端也要導入fastjson的兩個jar包
1、客戶端獲取json字符
這裏寫圖片描述這裏寫圖片描述
2、使用泛型獲取javaBean(核心函數)
這裏寫圖片描述

2、Gson一句代碼搞定Json的解析
(一) Gson簡介
谷歌GSON這個Java類庫可以把Java對象轉換成JSON,也可以把JSON字符串轉換成一個相等的Java對象。Gson支持任意複雜Java對象包括沒有源代碼的對象。

(二)Gson解析Json步驟
A、服務器端將數據轉換成json字符串
首先、服務器端項目要導入Gson的jar包到BuiltPath中。(
Gson的jar:http://code.google.com/p/google-gson/
然後將數據轉爲json字符串,核心函數是:
public static String createJsonString(Object value)
{
Gson gson = new Gson();
String str = gson.toJson(value);
return str;
}

B、客戶端將json字符串轉換爲相應的javaBean
首先客戶端也要導入gson的兩個jar包,json的jar就不需要導入了(因爲android項目中已經集成了json的jar包所以這裏無需導入)
1、客戶端獲取json字符串
這裏寫圖片描述這裏寫圖片描述
2、使用泛型獲取javaBean(核心函數)
這裏寫圖片描述

五、發佈 / 訂閱的事件總線
(一) Otto與EventBus
    這兩個框架的實現原理差不多, 在開發中常用Otto.
我們假設這樣一種業務場景,現在在做一款及時聊天應用,我們在聊天頁面進行收發信息,同時也要實時更新前一頁面的聊天記錄,這時我們該如何去實現?可以使用的是廣播接收器BroadCastReceiver,在接收和發送消息的時候就不停去發送廣播,然後在需要實時更新的地方進行接收更新。實現的思想比較簡單,也不存在代碼上的耦合問題,但是有個弊端。弊端就是需要去在很多地方實現BroadCastRecevier,代碼雖不算冗餘,但比較多,看起來很是不爽。使用Otto能解決代碼體積的問題。Otto是一款目前比較流行事件總線框架,旨在保持應用各頁面和模塊之間通信高效的前提下,對應用進行解耦。Otto是基於觀察者設計模式,簡單來說,如果你想訂閱某個消息,使用@Subcribe註解即可進行接收,同時使用
Bus.post(Object obj)進行消息的發佈,這樣的設計達到了完全的解耦。

Otto使用過程:
1、Bus實例化
    Bus這個類是整個框架的靈魂,它負責消息的發佈和接收,整個流程都是經過這個Bus去實現的。Bus的實例化推薦使用單例,就是說整個應用內只實例化一個Bus對象,所有的消息的處理都是經過這單一的實例去實現。因爲要實現消息的接受者接收到發佈的消息,一定要經過同一個Bus對象的處理。Bus的構造器可以接收ThreadEnforcer類型的參數,ThreadEnforcer其實是一個接口,它自身有兩個實現,分別表示Bus運行在Main Thread中還是異步線程中。
這裏寫圖片描述

2、註冊和解綁Bus
    根據具體的業務需求進行Bus的註冊和解綁,對於android中的組件,一般是基於生命週期方法中去實現;同時如果是任意你自定義的類中都可以進行。下面展示的是在Activity和Fragment裏面實現。
這裏寫圖片描述

3、消息的發佈
    發佈消息是整個框架中最重要的部分,它允許你告訴所有的訂閱者一個事件已經觸發。任何一個類的實例對象都可以通過總線Bus去發佈,同時也只能被訂閱這種對象的接受者所接收。下面展示的是通過Bus去發佈一個消息,消息的內容是LocationChangeEvent,所以LocationChangeEvent的接受者都能接收到此發佈的消息。注意的是,發佈消息只能一個Object對象。
這裏寫圖片描述

4、消息的訂閱
    消息的訂閱和發佈之前都要在當前的類中進行Bus的註冊。訂閱是對消息發佈的補充,當消息發佈的事件調用之後,對應的消息訂閱者就能立即接收到此消息。實現訂閱功能是通過自定義方法實現的,方法的名稱可以隨意,同時還得需要滿足三個條件。
這裏寫圖片描述
1、方法前使用@Subscribe註解
2、訪問修飾符爲public
3、單一參數,根據你想訂閱的消息進行設置
注:使用之前,記得進行註冊;使用完畢,記得釋放。

5、消息的produce
    當訂閱者註冊完畢,針對特定的消息,通常也需要獲取當前已知的值。這個時候,就需要用到produce。同樣的使用produce的方法名稱可以隨意,同時有三點需要注意。
1、方法前使用@produce註解
2、訪問修飾符爲public
3、無參,返回值是基於訂閱者參數類型
這裏寫圖片描述
    當然Otto的缺點也是有的,要實現上述訂閱/發佈模型的功能,付出的代價就是對各個註冊Bus的類進行反射。如果大量的使用的情況下,對應用的性能多少有點副影響。

實現原理:
    這個框架所實現的功能本質是在一個對象中調用任意的另一個或多個對象中的方法, 而不需要將這個或者這些對象傳入調用者. 如果把它們都傳入調用者去調用它們的方法, 那麼調用者就依賴這些對象, 程序的耦合度就高了, 所以說這個框架是用來解耦的.無論EventBus還是Otto都有一個註冊(register)的方法, 方法參數是需要訂閱事件的對象.register方法會拿到參數的class文件, Otto通過反射獲取類中有@Subscribe註解的方法, 將該Method對象和參數放入Otto內部的一個集合中, 在發佈事件時調用post方法, post方法會根據參數類型, 在這個集合中找到register時放入的相對應Method對象, 調用這個Method所需要的對象是register時傳入的參數, 所需的參數是post時傳入的參數, 這些都已經有了, 直接將它invoke EventBus與Otto不同僅在於Otto是通過註解來確定哪些方法是需要接收事件的方法, 而EventBus是通過固定的方法名來確定的, 所以在項目上線, 代碼混淆時, 使用了EventBus的類都不能混淆, 因此在項目中使用Otto會更多一點.

發佈了46 篇原創文章 · 獲贊 14 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章