Android的Lifecycle源碼分析

1. 簡(jiǎn)介

很早就聽(tīng)說(shuō)了Google的Lifecycle組件,因?yàn)轫?xiàng)目沒(méi)有使用過(guò),所以并沒(méi)有過(guò)多的接觸牺荠。不過(guò)最近看到了一篇文章,其中的一條評(píng)論提到了LiveData驴一。恰巧這兩天工作內(nèi)容不多休雌,所以趕緊研究一波!
不過(guò)在看LiveData之前肝断,我覺(jué)得還是先看下Lifecycle吧(Lifecycle更像是LiveData的基礎(chǔ)挑辆,LiveData就不寫(xiě)了,感覺(jué)沒(méi)啥東西)孝情。

2. Lifecycle的簡(jiǎn)單介紹

Lifecycle的介紹,我們還是拿Google的官方文檔作為參考吧洒嗤。
Lifecycle主要解決的是業(yè)務(wù)和Activity/Fragment生命周期相關(guān)的問(wèn)題箫荡。例如:我們?cè)?code>onResume()/onStart()中請(qǐng)求定位,在onPause()/onStop()中停止定位渔隶。那么我們一般的做法:

Google Simple Code
class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

上面的代碼雖然看起來(lái)還可以羔挡,但在真實(shí)的應(yīng)用程序中,可能會(huì)有很多的方法都需要根據(jù)當(dāng)前Activity/Fragment的生命周期來(lái)進(jìn)行不同的操作间唉。因此其生命周期方法中可能會(huì)被放置大量代碼绞灼,例如onStart()onStop()中,這使得它們難以維護(hù)呈野。因此Lifecycle應(yīng)運(yùn)而生低矮!

3. Lifecycle的使用

Lifecycle已經(jīng)發(fā)布了release版,所以其中的一些默認(rèn)支持已經(jīng)包含到了support-v7:26.1.0以及更高被冒。
添加依賴:

implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

使用方式1:實(shí)現(xiàn)LifecycleObserver接口军掂,使用@OnLifecycleEvent注解,通過(guò)編譯時(shí)注解生成代碼:

public class MyLifecycleObserver implements LifecycleObserver {

    private static final String TAG = MyLifecycleObserver.class.getSimpleName();

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void start(LifecycleOwner lifecycleOwner) {
        Lifecycle.State currentState = lifecycleOwner.getLifecycle().getCurrentState();
        Log.d(TAG, "start: " + currentState);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void stop(LifecycleOwner lifecycleOwner) {
        Log.d(TAG, "stop: " + lifecycleOwner.getLifecycle().getCurrentState());
    }
}

APT生成的代碼

使用方式2:實(shí)現(xiàn)GenericLifecycleObserver接口昨悼,實(shí)現(xiàn)其onStateChanged方法

public class MyLifecycleObserver implements GenericLifecycleObserver {

    private static final String TAG = MyLifecycleObserver.class.getSimpleName();

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        Log.d(TAG, event.name());
    }
}

創(chuàng)建完成后蝗锥,我們需要將其添加:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getLifecycle().addObserver(new MyLifecycleObserver());
    }
}

結(jié)果圖:


方法1

方法2

4. 源碼分析

  1. Lifecycle的獲取
    根據(jù)源碼追蹤我們可以看到Lifecycle是在SupportActivity中:
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}

這里還有個(gè)挺重要的代碼:

SupportActivity.java
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}
ReportFragment.java
public static void injectIfNeededIn(Activity activity) {
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        manager.executePendingTransactions();
    }
}

這里在Activity中添加了一個(gè)Fragment,至于作用率触,留到后面在講终议。

  1. addObserver
    addObserver方法的話,還是簡(jiǎn)單來(lái)看吧:
LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    ......
    // 對(duì)狀態(tài)的修正,這里會(huì)對(duì)已經(jīng)過(guò)去的狀態(tài)進(jìn)行分發(fā)穴张。也就是說(shuō)如果添加observer時(shí)狀態(tài)已經(jīng)改變细燎,那么也會(huì)被通知到!
}

// 有狀態(tài)的Observer
static class ObserverWithState {
    State mState;
    GenericLifecycleObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.getCallback(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

我們將實(shí)現(xiàn)的接口通過(guò)裝飾者(我認(rèn)為是這樣)模式轉(zhuǎn)成ObserverWithState對(duì)象陆馁,并將該對(duì)象添加到mObserverMap中找颓。
ObserverWithState的構(gòu)造方法中,有對(duì)我們傳入的LifecycleObserver進(jìn)行包裝:

Lifecycling.java
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
    // 這里應(yīng)該算第三種實(shí)現(xiàn)方式叮贩,然而FullLifecycleObserver不是public击狮,所以不能使用
    if (object instanceof FullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
    }
    // 我們的第一種方式
    if (object instanceof GenericLifecycleObserver) {
        return (GenericLifecycleObserver) object;
    }
    // 通過(guò)注解生成的
    final Class<?> klass = object.getClass();
    // 將生成的MyLifecycleObserver_LifecycleAdapter放到Map中
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
        List<Constructor<? extends GeneratedAdapter>> constructors =
                sClassToAdapters.get(klass);
        if (constructors.size() == 1) {
            GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                    constructors.get(0), object);
            return new SingleGeneratedAdapterObserver(generatedAdapter);
        }
        GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
        for (int i = 0; i < constructors.size(); i++) {
            adapters[i] = createGeneratedAdapter(constructors.get(i), object);
        }
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}

根據(jù)我們傳入的對(duì)象進(jìn)行解析,最終返回結(jié)果為:GenericLifecycleObserver或者GenericLifecycleObserver的實(shí)現(xiàn)類益老。附獲取生成MyLifecycleObserver_LifecycleAdapter代碼:

// 通過(guò)名稱獲取
public static String getAdapterName(String className) {
    return className.replace(".", "_") + "_LifecycleAdapter";
}

最終通過(guò)Class.forName方式獲得Class彪蓬。

  1. 事件分發(fā)
    Lifecycle的事件分發(fā)在ObserverWithState類中:
// 事件分發(fā)
void dispatchEvent(LifecycleOwner owner, Event event) {
    State newState = getStateAfter(event);
    mState = min(mState, newState);
    mLifecycleObserver.onStateChanged(owner, event);
    mState = newState;
}

看下哪里調(diào)用了dispatchEvent方法:

調(diào)用

我們看這個(gè)方法,其中一個(gè)在addObserver中調(diào)用捺萌,另外的兩個(gè)都會(huì)通過(guò)sync()方法調(diào)用:

// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
                + "new events from it.");
        return;
    }
    // 最新的狀態(tài)和當(dāng)前狀態(tài)不一致档冬,則需要進(jìn)行狀態(tài)修改
    while (!isSynced()) {
        mNewEventOccurred = false;
        // no need to check eldest for nullability, because isSynced does it for us.
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}
// 是否狀態(tài)同步的
private boolean isSynced() {
    if (mObserverMap.size() == 0) {
        return true;
    }
    // 最新的和最后添加的Observer狀態(tài)一致,并且當(dāng)前的狀態(tài)和最新?tīng)顟B(tài)一致桃纯,則已經(jīng)同步了
    State eldestObserverState = mObserverMap.eldest().getValue().mState;
    State newestObserverState = mObserverMap.newest().getValue().mState;
    return eldestObserverState == newestObserverState && mState == newestObserverState;
}

這里的同步方法用于同步當(dāng)前Observer的狀態(tài)酷誓,如果最新的和最老的Observer的狀態(tài)不一致或者當(dāng)前的狀態(tài)和最新的狀態(tài)不一致時(shí),那么需要進(jìn)行狀態(tài)同步态坦。同步包括了向前同步向后同步盐数。
調(diào)用sync()方法一共就兩處,一處在addObserver方法伞梯,另一處是moveToState方法玫氢,而調(diào)用moveToState方法也有兩處:

@SuppressWarnings("WeakerAccess")
@MainThread
public void markState(@NonNull State state) {
    moveToState(state);
}

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

handleLifecycleEvent方法有很多處調(diào)用:

handleLifecycleEvent調(diào)用

看圖的話,就可以知道Fragment在不同的生命周期調(diào)用了handleLifecycleEvent方法谜诫,隨便看一個(gè)吧:
ON_CREATE

還記得上面說(shuō)的ReportFragment嗎漾峡?這里也出現(xiàn)了,我們看下ReportFragment到底做什么的:

// 調(diào)用Activity的
private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

// 生命周期
@Override
public void onDestroy() {
    super.onDestroy();
    dispatch(Lifecycle.Event.ON_DESTROY);
    // just want to be sure that we won't leak reference to an activity
    mProcessListener = null;
}

可以看到喻旷,ReportFragment只是作為一個(gè)中間層生逸,通過(guò)它來(lái)分發(fā)各種事件!
由于篇幅原因(已經(jīng)啰嗦了很多了)且预,這里就不寫(xiě)LifecycleDispatcherProcessLifecycleOwner了牺陶,這兩個(gè)通過(guò)自定義的內(nèi)容提供者ProcessLifecycleOwnerInitializer進(jìn)行初始化,并且通過(guò)registerActivityLifecycleCallbacksregisterFragmentLifecycleCallbacks注冊(cè)統(tǒng)一的觀察回調(diào)辣之。有興趣的話掰伸,自己看看吧。

5 總結(jié)

Lifecycle簡(jiǎn)單來(lái)說(shuō)就是用于處理和生命周期相關(guān)的業(yè)務(wù)怀估,其原理以及實(shí)現(xiàn)還是很簡(jiǎn)單的狮鸭。當(dāng)然了合搅,項(xiàng)目中并沒(méi)有使用到Lifecycle,所以實(shí)際應(yīng)用效果怎樣只能靠猜想了??歧蕉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末灾部,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子惯退,更是在濱河造成了極大的恐慌赌髓,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件催跪,死亡現(xiàn)場(chǎng)離奇詭異锁蠕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)懊蒸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)荣倾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人骑丸,你說(shuō)我怎么就攤上這事舌仍。” “怎么了通危?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵铸豁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我菊碟,道長(zhǎng)节芥,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任框沟,我火速辦了婚禮,結(jié)果婚禮上增炭,老公的妹妹穿的比我還像新娘忍燥。我一直安慰自己,他們只是感情好隙姿,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布梅垄。 她就那樣靜靜地躺著,像睡著了一般输玷。 火紅的嫁衣襯著肌膚如雪队丝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天欲鹏,我揣著相機(jī)與錄音机久,去河邊找鬼。 笑死赔嚎,一個(gè)胖子當(dāng)著我的面吹牛膘盖,可吹牛的內(nèi)容都是我干的胧弛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼侠畔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼结缚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起软棺,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤红竭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后喘落,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體茵宪,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年揖盘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了眉厨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兽狭,死狀恐怖憾股,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情箕慧,我是刑警寧澤服球,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站颠焦,受9級(jí)特大地震影響斩熊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伐庭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一粉渠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧圾另,春花似錦霸株、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扰路,卻和暖如春尤溜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背汗唱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工宫莱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哩罪。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓梢睛,卻偏偏與公主長(zhǎng)得像肥印,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绝葡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容