LiveData小知識點,何時註冊Observer

LiveData學習使用

記錄一個在使用LiveData是遇到的有趣問題。由這個問題我們知道,在Activity中設置LiveData的Observer的時候,需要在onCreate中去設置。

起初些demo。主要是爲了驗證在SecondActivity,改變LiveData的值的時候,MainActivity的Observer何時被回調。
MainActivity代碼
MainActivity的代碼
SecondActivity的代碼
在這裏插入圖片描述
功能其實非常簡單,定義一個單例的LiveData對象,然後在SecondActivity中改變LiveData的值,看MainActivity中的Observer是否會回調。
結論是再沒有回到MainActivity的時候自然不會被回調,這個是符合預期的。
但是有一點我呢提,我發現回到MainActivity之後,居然執行了兩次回調。日誌如下。在這裏插入圖片描述
怎麼回事呢,看了一下,我設置監聽是在onResume中,再次回到Main的時候又會設置一次監聽,但是值已經變化了啊,爲什麼還會被回調呢。那肯定就是在添加observer的時候還有些判斷,可以直接觸發回調。看下LiveData的observer源碼。
在這裏插入圖片描述
那就應該是標紅的這一行中有觸發回調的邏輯了。進到方法看一下。實際實現是在LifecycleRegistry.java中,代碼如下

public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        // 判斷這個observer對象是否已經被添加過了,所以如果不想重複觸發可以講傳入的observer設爲成員變量,後面講一下
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        if (previous != null) {
            return;
        }
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            // it is null we should be destroyed. Fallback quickly
            return;
        }

        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
        // ** 重點就在於這個state的計算 ,下一段代碼就關於state的計算**
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }

        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }
private State calculateTargetState(LifecycleObserver observer) {
        Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

        State siblingState = previous != null ? previous.getValue().mState : null;
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        return min(min(mState, siblingState), parentState);
    }

按照現在的這種講Observer註冊寫道onResume中,LiveData被改變一次,只要Main沒有被Destroy,每次進入Main頁面都要走一次回調,這肯定是不行的。

根據源碼展示,有兩種方法,一種是在onCreate中註冊,其實這本就是標準用法。另一種方法是將observer對象設置爲成員變量(這一點我們可以從源碼中看到)。具體方法可以自己看看。

今天還看了一下Jetpack中的Room,結合LiveData使用,簡直是無敵了。過幾天也寫一下自己的理解。

總結

最近一直在找工作,因爲感覺在OPPO繼續待著,做的業務也沒啥意思了,很想做新模塊的開發,可是連續面了五家,全部倒再一面,我還是兩年前第一次找工作那樣,什麼問題我都能回答一些,但是往深了問就不知道了。兩年前憑藉面試表現,怎麼面試都能拿下offer,因爲當時作爲一個工作一年的人來說我所掌握的知識的廣度和深度,的確是比大部分人優秀的。但是現在我已經是一個工作三年的人了,對於基礎知識的深度還是和以前一樣,廣度甚至變小了。在OPPO一直是埋頭幹事情,對現有模塊添加一點東西,或者解決一些繁瑣的業務bug。不涉及架構設計能力的提升,也不用學習任何的新東西,我就完全能夠應付現有的工作需要。並且19年一整年,都是十點半以後下班的節奏,整個人都是非常疲憊的,接着就是完全忽略了對新技術的學習。也不再關注行業動態了。起先我一直都在埋怨OPPO這種沒有技術氛圍的工作環境,但是現在我才逐漸意識到,其實這些環境是一小部分因素,重點還是自己怎麼做。我的室友,作爲一名產品經理,每天比我回來的還晚,但是19年他看了大概有將近二十本書,並且大多數時候都是七點起牀去健身。時間是靠自己爭取的,知識也是靠自己汲取的。所以我覺得我需要重新開始好好學習一些非常好的東西。並且好好複習基礎知識,即使我還是沒辦法找到心儀的工作,即使我可能還要繼續留在OPPO,但是我一定會成爲更優秀的人,我要爲自己正名。

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