Activity & Fragment - 生命周期和状态保存

Activity’s Lifecycle

Fragment’s Lifecycle

Saving activity state

  • Activity save state - onSaveInstanceState(Bundle outState)

    • Activity的状态保存在onStop()之前,但可能在onPause()之前也可能之后

    • 实例: 有两个Activity A和B,当从A跳到B时,A会保存自己的状态;当B返回A时,B不会保存自己的状态;但当在B中按Home键,B会保存自己的状态.

  • Activity restore state - onRestoreInstanceState(Bundle savedInstanceState)

    • 恢复在Activity-onSaveInstanceState时保存的状态

    • Activity的状态恢复发生在onStart和onPostCreate之间

Saving fragment state

  • Fragment save state - onSaveInstanceState(Bundle outState)

    • 保存Fragment的状态,当重新创建该Fragment的实例时,恢复之前保存的状态。保存的状态(Bundle)将被传给Fragment的onCreate(Bundle)},onCreateView(LayoutInflater, ViewGroup, Bundle), and onActivityCreated(Bundle)

    • Fragment在onSaveInstanceState之后,只有当Fragment的实例改变时,save的状态才能被恢复

    • 当Activity执行onSaveInstanceState(Bundle)时,该Activity的所有Fragment也会去保存状态

    • onSaveInstanceState方法可能会在onDestroy()之前的任何时刻被调到

    • 在某些情况下Fragment的状态不会被保存直到它的Activity保存状态时,比如Fragment不可见了并且被放进了back stack中

  • Fragment restore state - onViewStateRestored(@Nullable Bundle savedInstanceState)

    • 恢复Fragment已保存的状态

    • onViewCreated() called before any saved state has been restored in to the view

    • onViewStateRestored在onActivityCreated(Bundle)之后,在onStart()之前

  • FragmentTransaction - commit()

    • 由于commit()之后Fragment保存的状态就会丢掉,所以commit操作不能在save state后做。

实例分析

  • 关于Fragment中WebView状态保存和恢复

    • 现象: 在一个Fragment(A)中有一个WebView,在WebView中可以通过某些链接跳到另一个Fragment(B)中,这样再从B返回A,A中WebView的状态将会丢失它会重新加载WebView使回到初始状态.

    • 原因: 当从A跳到B时,A只是销毁了view并没有destroy,所以并没有保存状态,自然WebView的状态也就丢失了.
      那么如果我手动的调用一次onSaveInstanceState然后再让Fragment去恢复状态这样是否可行?答案是不可行,因为Fragment在onSaveInstanceState之后,只有当Fragment的实例改变时,save的状态才能被恢复,在这里显然A Fragment的实例并没有被销毁,所以自然状态无法恢复.

    • 一种解决方案: 在Fragment onPause时保存WebView的状态,在创建View的时候恢复状态

    • Demo: 当在Fragment ONE中点击文章最后参考中的Activity链接,再点击Activity页面的Activity链接,这样会进入Fragment TWO.当没有自己保存web view的状态时,点击返回键将回到Fragment one的初始页面即博客页面,要想回到Fragment one掉转之前的状态就需要自己去保存并恢复.

参考