Android面試專題系列(四):Activity之間如何進行通信→LiveDataBus

不詩意的女程序媛不是好廚師~
轉載請註明出處,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使用更爲方便,並且沒有內存泄漏風險。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章