Activity和Fragment之間的聯繫和區別

Android開發中,Acitivity是四大組件中用得非常多的一個組件,也是UI和業務邏輯的一個重要的紐帶,那麼它和與它很類似的Fragment有哪些聯繫和區別呢?現在主要從生命週期來談談自己的看法。另外也順便看看onSaveInstanceState這個方法大體是怎麼保存狀態並在onCreate中恢復狀態的。

圖1、Activity的生命週期

這裏寫圖片描述

首先看Activity的生命週期,有:
onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()、onRestart()
其中:
onCreate()和onDestroy()是成對關係
onStart()和onStop()是成對關係
onResume()和onPause()是成對關係

然後看Activity的幾種狀態:
運行狀態、暫停狀態、停止狀態、銷燬狀態
Activity的幾種生存期:
完整生存期、可見生存期、前臺生存期

根據生命週期、狀態、生存期對Activity做一個解釋分析
運行狀態:當一個活動位於返回棧的棧頂時該活動就是處於運行狀態
暫停狀態:當一個活動不處於棧頂位置但仍然可見時,活動處於暫停狀態(比如在對話框後面的activity)
停止狀態:當一個活動不再處於棧頂位置並且完全不可見時,活動處於停止狀態
銷燬狀態:當一個活動從返回棧中移除後就變成了銷燬狀態

完整生存期:活動從onCreate()到onDestroy()之間經歷的就是完整生存週期
可見生存期:活動在onStart()到onStop()之間經歷的就是可見生存期。此時活動可見,即便可能不能與用戶交互。
前臺生存期:活動在onResume()到onPause之間經歷的就是前臺生存期。此時活動可見並且能與用戶交互。

Activity之間的生命週期狀態轉換:
當另一個活動來到前臺,此活動onPause()方法執行;此活動重新返回前臺,此活動onResume()方法執行。
當此活動不可見,此活動onStop()方法執行;此活動重新可見返回前臺,onStart()方法執行。
當此活動不處於前臺甚至不可見時,一個優先級更高的線程需要內存,當前活動被kill掉,重新返回該活動時,onCreate()方法執行。

圖2、Fragment的生命週期

這裏寫圖片描述

然後再看看Fragment的生命週期
因爲Fragment和Activity是可以通信的,Fragment是一種控制器對象,Activity可以委派它完成一個任務,這些任務通常就是管理用戶界面(Activity通過findFragmetById獲得Fragment的一個實例,Fragment通過getActivy獲得Activity的實例和Context)。
Activity知道如何管理Fragment,因此Fragment的使用需要Activity的支持,使得Fragment的生命週期和Activity的生命週期非常像,很多方法名稱都和Activity是一樣的。

Fragment的運行狀態:
運行狀態:當fragment可見,並且它關聯的activity處於運行狀態,此fragment也處於運行狀態。
暫停狀態:當一個activity進入暫停狀態(比如對話框等未佔滿屏幕的activity進入棧頂),fragment也進入到暫停狀態
停止狀態:當一個activity進入停止狀態,與之關聯的fragment也進入停止狀態;或者通過fragment事務的remove和replace方法將fragment移除。如果在事務commit之前調用了addToBackStack()方法,這時的fragment也會停止
銷燬狀態:Fragment依附Activity存在,當activity被銷燬,與之關聯的fragment也被銷燬。或者通過fragment事務的remove和replace方法將fragment移除。如果在事務commit之前沒有調用addToBackStack()方法,這時的fragment也會銷燬

Fragment相對Activity添加的回調方法
onAttach():當fragment和activity建立關聯的時候調用
onCreateView():爲fragment創建視圖調用,在onCreate之後
onActivityCreated():確保與fragment相關聯的activity一定已經創建完畢的時候調用
onDestroyView():當與fragment關聯的視圖被移除的時候調用
onDetach():當fragment與activity解除關聯時調用

onAttach()與onDetach()是一組
onCreateView()與onDestroyView()是一組

順便講講狀態保存於狀態恢復的源碼:

這是onSaveInstanceState(保存狀態)方法的源碼

protected void onSaveInstanceState(Bundle outState) {
    outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
    Parcelable p = mFragments.saveAllState();
    if (p != null) {
        outState.putParcelable(FRAGMENTS_TAG, p);
    }
    getApplication().dispatchActivitySaveInstanceState(this, outState);
}

這是onCreate的源碼

protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
    if (mLastNonConfigurationInstances != null) {
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    }
    if (mActivityInfo.parentActivityName != null) {
        if (mActionBar == null) {
            mEnableDefaultActionBarUp = true;
        } else {
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        }
    }
    if (savedInstanceState != null) {
        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    if (mVoiceInteractor != null) {
        mVoiceInteractor.attachActivity(this);
    }
    mCalled = true;
}

onSaveInstanceState方法中的大意是:保存Window的State信息,保存所有Fragment的信息(通過Parcelable將所有的狀態打包存入一個名爲 FRAGMENTS_TAG 的對象中),獲取當前應用環境使用dispatchActivitySaveInstanceState(this, outState)方法保存outState到當前Context中。
onCreate方法就是對保存的狀態依次作解析。
更具體的分析可以查看一些大神的解釋,如有侵權請聯繫刪除。
【Android面試】(二):你不能不知道的view—加id和不加id的區別?
Android中SaveState原理分析

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