不詩意的女程序媛不是好廚師~
轉載請註明出處,From李詩雨—https://blog.csdn.net/cjm2484836553/article/details/105147592
《Android面試專題系列四》Activity之間如何進行通信→LiveDataBus
現在當面試官問你:“Activity之間如何進行通信?”
其實他想聽到的答案並不是:Intent , Handler,EventBus , RxBus ,廣播。
上面說的這些都有些老舊和原始了,其實他想聽到的是 LiveDataBus !
從18年穀歌IO大會開始 官方建議:
在Activity與Activity ,Activity與Fragment,Fragment與Fragment之間通信使用LivedataBus。
那LiveDataBus是什麼呢?
它憑什麼就能PK掉 Handler,EventBus , RxBus 呢?
它又有什麼明顯的優勢呢?
彆着急,我們先從一個最簡單的例子說起:
【先描述一下上面的demo】
在MainActivity中有一個按鈕Button,點擊Button會跳轉到Bactivity。
來到 Bactivity時 ,我們會收到由MainActivity發送來的消息 “面試加油!”。
並且以吐司的方式顯示出來。
看完了效果,我們再來看看代碼是怎麼實現的吧。
【代碼實現】
①在MainActivity中,當我們點擊按鈕時,發送一個消息:
public void click(View view) {
//發送消息
LiveDataBus.getInstance().with("msg", String.class).postValue("大家好!");
Intent intent=new Intent(this,SecActivity.class);
startActivity(intent);
}
②在Bactivity中,定義一個接收數據的觀察者,並以吐司的形式顯示數據。
//定義一個接收數據的觀查者
LiveDataBus.getInstance().with("msg", String.class).observe(
this, new Observer<String>() {
@Override
public void onChanged(String msg) {
if(msg!=null){
Toast.makeText(SecActivity.this, msg, Toast.LENGTH_SHORT).show();
}
}
}
);
③最後我們來看看我們 極簡版 的LiveDataBus.
/**
* 這條總線用於把任何類中的數據直接傳遞到activity或是fragment上
*/
public class LiveDataBus {
//存放訂閱者
private Map<String, MutableLiveData<Object>> bus;
private static LiveDataBus liveDataBus = new LiveDataBus();
private LiveDataBus() {
bus = new HashMap<>();
}
public static LiveDataBus getInstance() {
return liveDataBus;
}
//註冊訂閱者,(存入map)
public synchronized <T> MutableLiveData<T> with(String key, Class<T> type) {
if (!bus.containsKey(key)) {
bus.put(key, new MutableLiveData<Object>());
}
return (MutableLiveData<T>) bus.get(key);
}
}
好了,就這麼多代碼,怎麼樣 是不是感覺很簡單。
【使用說明】
發送消息時的圖:
接收消息時的圖:
根據圖我再來解釋一下:
-
當我們要發送消息的時候,我們就調用
LiveDataBus.getInstance().with(
的這個api,設置一個鍵,設置一個value的類型(value可以爲任意類型),要發送消息的時候我們就調用postValue()
,並把要發送的內容放進去。 -
發出去以後,在程序的任何其他地方(比如說是Activity或者Fragment),只要它也定義了一個觀察者,並且它的鍵也是
“msg”
,那麼這個觀察者就可以收到postValue中發出的Value值。 -
我們定義的觀察者中會有一個
onChanged()
回調,在onChanged()
裏我們就會得到從MainActivity發送來的數據。
【分析原理】
好的,下面我們就可以來分析分析它到底是怎麼實現的了。
一圖解百愁,還是先給大家來畫個圖:
-
首先,我們設計一個LiveDataBus的總線,這個總線上面會註冊很多信息。
總線上會持有一個hashMap ,以key-value的形式存放數據,key(String),value(MutableLiveData)。
並且這個總線是一個單例模式。
-
當我發送消息的時候,我們使用的api是
LiveDataBus.getInstance().with...
,當這個消息發送出去以後,它會把這個消息註冊到HashMap
裏面去,對應的key
就是"msg"
。 -
這個消息註冊過以後,我們再來看看使用的地方:使用它的時候會去綁定一個觀察者。
使用的過程中實際上使用的是同一個api即
LiveDataBus.getInstance().with...
,這個api的返回值都是一個
MutableLiveData
,所以,實際上它就把這個observe綁定到
MutableLiveData
上了。
我們來看看這個MutableLiveData
是什麼吧。
MutableLiveData
繼承自LiveData
:
我們進入LiveData的源碼再往下看,會發現一個considerNotify()方法:
這就是一個通知,通過我們的通知 去通知我們的觀察者 執行onChanged()。
以上就是我們的具體執行流程分析了。
下面我們來做個小結~
【小結】
LiveEventBus是一款Android消息總線,基於LiveData,具有生命週期感知能力,支持Sticky,支持AndroidX,支持跨進程,支持跨APP。
關於爲什麼它具有生命感知能力,大家可以從源碼角度來說。
即它實際上是和Glide感知生命週期一樣的,內部都創建了一個空的Fragment。
LiveDataBus 與 EventBus、RxBus的 比較
-
LiveDataBus 與 EventBus 的比較:
LiveDataBus的實現及其簡單,相對EventBus複雜的實現,LiveDataBus只需要一個類就可以實
-
LiveDataBus 與 RxBus 的比較:
LiveDataBus可以減小APK包的大小 並且 依賴支持也更好。因爲 LiveDataBus只依賴Android官方組件LiveData,本身實現只一個類。而RxBus需要依賴RxJava和RxAndroid。
-
最後還有一點 LiveDataBus具有生命週期感知。
在Android系統中使用調用者不需要調用反註冊,相比EventBus和RxBus使用更爲方便,並且沒有內存泄漏風險。