1 研發背景
案例:咱們在主頁點收藏按鈕,未登陸狀態,跳登陸界面,在登陸界面跳註冊頁面,註冊成功,關閉註冊頁面,關閉登陸頁面,回到主頁,刷新item列表和登陸狀態。
咱們通常會用到發送廣播和接收廣播來實現。本地廣播是相對消耗時間、空間最多的一種方式,是重量級的,消耗資源較多的一種方式。四大組件之一,許多系統級的事件都是經過廣播來通知的。好比網絡變化,電量變化,短信發送接收。
若是與系統相關的通知,仍是選擇本地廣播。在廣播的onreceive方法中,能夠得到context,intent參數,有豐富的api供咱們使用。若是與系統事件不相關的交互,使用廣播是一種浪費。由此,咱們可使用EventBus來實現相關需求。
2 EventBus簡介
EventBus 是一款針對Android優化的發佈/訂閱事件總線。主要功能是替代intent,handler,broadcast在fragment,activity,service,線程之間的傳遞消息。
EventBus做爲Android開發經常使用框架,有許多優勢:
1 調度靈活,不依賴context。
2 使用簡單,代碼簡潔。
3 鬆耦合。有效地下降消息發佈者和訂閱者之間的耦合度。
當想通知其餘組件某些事情發生時經常使用觀察者模式。EventBus是一個觀察者模式的實現,有三個要素:
1 Event 事件:能夠是任意類型對象
2 Subscriber 訂閱者,接收特定的事件,以約定的onEvent開頭的函數,有4種
3 Publisher 事件發佈者,用於通知Subscriber有事件發生,能夠經過post(object)在任意線程任意位置發送事件
額外一點,訂閱者能夠訂閱多個事件,發送者能夠發佈任何事件,發佈者同時也能夠是訂閱者。
EventBus架構圖:
3 EventBus 3.0使用
project目錄build.gradle 添加classpath: classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
module目錄build.gradle 添加plugin:apply plugin:'android-apt';添加依賴: compile 'com.greenrobot:eventbus:3.0.0’
(1) 定義事件
public class AnyEventType{
}
(2) 在要接收消息的頁面註冊
EventBus.getDefault().register(this);
(3) 接收消息(共有四個函數,選擇實現下列任一 一個)
一、onEvent 事件處理和事件發送在相同線程,事件處理時間不該太長,否則影響事件的發送線程。
二、onEventMainThread 事件的處理在UI線程執行。事件處理時間不能太長,以防出現ANR
三、onEventBackgroundThread 事件處理在一個後臺線程中執行,時間不能太長
四、onEventAsync 事件處理在單獨的線程中執行,主要用於在後臺中執行 耗時操做,每一個事件會開啓一個線程,但最好限制線程的數目。
(4) 發送消息
EventBus.getDefault().post("resiterSuccess");
(5) 解除註冊
EventBus.getDefault().unregister(this);
告知觀察者事件發生時經過EventBus.post函數實現,這個過程叫作事件的發佈,觀察者被告知事件發生叫作事件的接收,是經過下面的訂閱函數實現的。
onEvent:若是使用onEvent做爲訂閱函數,那麼該事件在哪一個線程發佈出來的,onEvent就會在這個線程中運行,也就是說發佈事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操做,若是執行耗時操做容易致使事件分發延遲。
onEventMainThread:若是使用onEventMainThread做爲訂閱函數,那麼不論事件是在哪一個線程中發佈出來的,onEventMainThread都會在UI線程中執行,接收事件就會在UI線程中運行,這個在Android中是很是有用的,由於在Android中只能在UI線程中跟新UI,因此在onEvnetMainThread方法中是不能執行耗時操做的。
onEventBackground:若是使用onEventBackgrond做爲訂閱函數,那麼若是事件是在UI線程中發佈出來的,那麼onEventBackground就會在子線程中運行,若是事件原本就是子線程中發佈出來的,那麼onEventBackground函數直接在該子線程中執行。
onEventAsync:使用這個函數做爲訂閱函數,那麼不管事件在哪一個線程發佈,都會建立新的子線程在執行onEventAsync.
問題 這4個方法是否會同時觸發?選擇哪個觸發?
當發過來一個消息的時候,EventBus怎麼知道要調哪一個函數呢,就看onEvent函數傳進去的參數與發送消息的參數類型是否一致,哪一個是就調哪一個。那若是有兩個是呢,那兩個都會被調用!!!!
識別EventBus中四個函數中觸發哪個,是經過參數中的類名來決定的。