Lifecycle_原理解析

一唤反、使用Lifecycle

1. 引入Lifecycle

我們來看一下如何引入:

1.非androidX項目引入:

//運行時
implementation "android.arch.lifecycle:runtime:1.1.1"
// 編譯期
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

2.androidX項目引入:

implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation "androidx.lifecycle:lifecycle-common-java8:2.0.0"
annotationProcessor  "androidx.lifecycle:lifecycle-compiler:2.0.0"

2. 創(chuàng)建生命周期觀察者

我們首先創(chuàng)建了一個類,它實現(xiàn)了LifecycleObserver接口,并且我寫了幾個模擬生命周期的方法,并在每個方法上加上了日志.

public class MyObserver implements LifecycleObserver {

    private static final String TAG = "MyObserver";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)  
    public void onCreate() {
        Log.w(TAG, "onCreate: ");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        Log.w(TAG, "onStart: ");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        Log.w(TAG, "onResume: ");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        Log.w(TAG, "onPause: ");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        Log.w(TAG, "onStop: ");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.w(TAG, "onDestroy: ");
    }
}

3. 注冊觀察Activity生命周期

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //添加一個生命周期觀察者    getLifecycle()是FragmentActivity中的方法
        MyObserver observer = new MyObserver();
        getLifecycle().addObserver(observer);
    }
}

觀察運行打印日志

2019-03-12 22:14:26.672 15790-15790/? W/MyObserver: onCreate: 
2019-03-12 22:14:26.676 15790-15790/? W/MyObserver: onStart: 
2019-03-12 22:14:26.679 15790-15790/? W/MyObserver: onResume: 
2019-03-12 22:15:13.054 15790-15790/? W/MyObserver: onPause: 
2019-03-12 22:15:13.234 15790-15790/? W/MyObserver: onStop: 
2019-03-12 22:15:13.241 15790-15790/? W/MyObserver: onDestroy: 

為此我們可以用這個來觀察acitvity生命周期谱仪,并及時處理回收處理等操作,保證內(nèi)存泄漏等問題匈子。

二、Lifecycle原理解析

1.activity是如何分發(fā)生命周期的撞反?

我們從使用入手似扔,點擊getLifecycle()

MyObserver observer = new MyObserver();
getLifecycle().addObserver(observer);

我們看到mLifecycleRegistry是ComponentActivity的一個成員變量,用來管理向其注冊生命周期觀察者

public class ComponentActivity extends Activity
        implements LifecycleOwner, KeyEventDispatcher.Component {
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }   
}

LifecycleRegistry是Lifecycle的一個實現(xiàn),而Lifecycle是一個抽象類,里面有3個方法(添加觀察者和移除觀察者,獲取當前的狀態(tài))

public abstract class Lifecycle {

    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);


    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);


    @MainThread
    @NonNull
    public abstract State getCurrentState();

    @SuppressWarnings("WeakerAccess")
    public enum Event {
        /**
         * Constant for onCreate event of the {@link LifecycleOwner}.
         */
        ON_CREATE,
        /**
         * Constant for onStart event of the {@link LifecycleOwner}.
         */
        ON_START,
        /**
         * Constant for onResume event of the {@link LifecycleOwner}.
         */
        ON_RESUME,
        /**
         * Constant for onPause event of the {@link LifecycleOwner}.
         */
        ON_PAUSE,
        /**
         * Constant for onStop event of the {@link LifecycleOwner}.
         */
        ON_STOP,
        /**
         * Constant for onDestroy event of the {@link LifecycleOwner}.
         */
        ON_DESTROY,
        /**
         * An {@link Event Event} constant that can be used to match all events.
         */
        ON_ANY
    }


    @SuppressWarnings("WeakerAccess")
    public enum State {

        DESTROYED,


        INITIALIZED,


        CREATED,


        STARTED,


        RESUMED;


        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}

2.竟然有了觀察管理者LifecycleRegistry,它又是如何分發(fā)生命周期的呢垄惧?

點擊進入ComponentActivity的onCreate()方法刁愿,里面有ReportFragment,看名字是不是很熟悉赘艳,難道這個就是用來上報Activity生命周期的酌毡?

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}

沒錯,其實ReportFragment就是在Activity中添加一個空白Fragment,有Fragment的生命周期,當然我們就知道了Activity的生命周期,接著通知相關的觀察者即可.

public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        // ProcessLifecycleOwner should always correctly work and some activities may not extend
        // FragmentActivity from support lib, so we use framework fragments for activities
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
}

其實這個injectIfNeededIn()看起來像是注入的方法干的就是將Fragment添加到Activity中,

來看看這個ReportFragment的生命周期方法都干了些啥,

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    dispatch(Lifecycle.Event.ON_START);
}

private void dispatchCreate(ActivityInitializationListener listener) {
    if (listener != null) {
        listener.onCreate();
    }
}

通過調(diào)用dispatchCreate(mProcessListener)方法,感覺從命名上看分發(fā)當前的生命周期事件.
dispatch(Lifecycle.Event.ON_START); 也像是在分發(fā)事件.

我們跟著這個mProcessListener來看看是在哪里設置的

/**
 * Class that provides lifecycle for the whole application process.
 */
public class ProcessLifecycleOwner implements LifecycleOwner {
    
    //注意,我是一個單例
    private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();

    static void init(Context context) {
        sInstance.attach(context);
    }

    void attach(Context context) {
        mHandler = new Handler();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ReportFragment.get(activity).setProcessListener(mInitializationListener);
            }
    
            @Override
            public void onActivityPaused(Activity activity) {
                activityPaused();
            }
    
            @Override
            public void onActivityStopped(Activity activity) {
                activityStopped();
            }
        });
    }
}

//Activity的監(jiān)聽器
ActivityInitializationListener mInitializationListener =
            new ActivityInitializationListener() {
                @Override
                public void onCreate() {
                }

                @Override
                public void onStart() {
                    activityStarted();
                }

                @Override
                public void onResume() {
                    activityResumed();
                }

private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

//Activity創(chuàng)建的時候,分發(fā)Lifecycle.Event.ON_START事件
void activityStarted() {
    mStartedCounter++;
    if (mStartedCounter == 1 && mStopSent) {
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
        mStopSent = false;
    }
}
ReportFragment.java
static ReportFragment get(Activity activity) {
    return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
            REPORT_FRAGMENT_TAG);
}

ProcessLifecycleOwner的attach()中registerActivityLifecycleCallbacks()注冊了一個監(jiān)聽器,一旦有Activity創(chuàng)建就給它設置一個Listener.這樣就保證了每個ReportFragment都有Listener.

既然是一個全局的單例,并且可以監(jiān)聽整個應用程序的生命周期,那么,肯定一開始就需要初始化. 既然沒有讓我們在Application里面初始化,那么肯定就是在ContentProvider里面初始化的.

3. ProcessLifecycleOwner 在ContentProvider初始化

public class ProcessLifecycleOwnerInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
}

1.ProcessLifecycleOwner初始化就不說了,是拿來觀察整個應用的生命周期的,其原理就是利用ReportFragment,我們稍后詳細到來.
2.LifecycleDispatcher尤其重要.

class LifecycleDispatcher {
    static void init(Context context) {
        ...
        //registerActivityLifecycleCallbacks  注冊一個監(jiān)聽器
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }
}
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        //又來注入咯
        ReportFragment.injectIfNeededIn(activity);
    }
    @Override
    public void onActivityStopped(Activity activity) {
    }
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }
}

初始化的時候,就注冊了一個監(jiān)聽器,每個創(chuàng)建的時候都給它注入一個ReportFragment.
那為什么在Activity onCreate還要再注入一個ReportFragment,可能2次注入,確保萬無一失,但不管注冊幾次蕾管,內(nèi)部實現(xiàn)是只會成功注入一次的,所以多調(diào)用一次,無所謂

4.事件分發(fā)

前面講的有點啰嗦枷踏,接下來我們來看下是如何一步一步分發(fā)生命周期事件的

ReportFragment.java
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    dispatch(Lifecycle.Event.ON_CREATE);
}

private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        //獲取Activity中的LifecycleRegistry
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

private void moveToState(State next) {
    ......
    sync();
    ......
}

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    
    //循環(huán) 遍歷所有觀察者
    while (...) {
        ....
        //分發(fā)事件
        forwardPass(lifecycleOwner);
    }
}

注意看分發(fā)生命周期會根據(jù)狀態(tài),小于當前狀態(tài)的都會一并分發(fā)

private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            //分發(fā)事件
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掰曾,一起剝皮案震驚了整個濱河市旭蠕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖掏熬,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佑稠,死亡現(xiàn)場離奇詭異,居然都是意外死亡旗芬,警方通過查閱死者的電腦和手機舌胶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疮丛,“玉大人幔嫂,你說我怎么就攤上這事√鼙。” “怎么了履恩?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呢蔫。 經(jīng)常有香客問我切心,道長,這世上最難降的妖魔是什么片吊? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任绽昏,我火速辦了婚禮,結(jié)果婚禮上定鸟,老公的妹妹穿的比我還像新娘而涉。我一直安慰自己,他們只是感情好联予,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布啼县。 她就那樣靜靜地躺著,像睡著了一般沸久。 火紅的嫁衣襯著肌膚如雪季眷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天卷胯,我揣著相機與錄音子刮,去河邊找鬼。 笑死窑睁,一個胖子當著我的面吹牛挺峡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播担钮,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼橱赠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了箫津?” 一聲冷哼從身側(cè)響起狭姨,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宰啦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饼拍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赡模,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年师抄,在試婚紗的時候發(fā)現(xiàn)自己被綠了漓柑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡叨吮,死狀恐怖欺缘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挤安,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布丧鸯,位于F島的核電站蛤铜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丛肢。R本人自食惡果不足惜围肥,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜂怎。 院中可真熱鬧穆刻,春花似錦、人聲如沸杠步。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幽歼。三九已至朵锣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甸私,已是汗流浹背诚些。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皇型,地道東北人诬烹。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像弃鸦,于是被迫代替她去往敵國和親绞吁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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