和活動一樣,碎片也有自己的生命周期,並且它和活動的生命周期實在是太像了,我相 信你很快就能學會,下面我們馬上就來看一下。
4.3.1 碎片的狀態和回調
還記得每個活動在其生命周期內可能會有哪幾種狀態嗎?沒錯,一共有運行狀態、暫停 狀態、停止狀態和銷毀狀態這四種。類似地,每個碎片在其生命周期內也可能會經歷這幾種 狀態,只不過在一些細小的地方會有部分區別。
1. 運行狀態 當一個碎片是可見的,並且它所關聯的活動正處於運行狀態時,該碎片也處於運行
狀態。
2. 暫停狀態
當一個活動進入暫停狀態時(由於另一個未占滿屏幕的活動被添加到了棧頂),與 它相關聯的可見碎片就會進入到暫停狀態。
3. 停止狀態 當一個活動進入停止狀態時,與它相關聯的碎片就會進入到停止狀態。或者通過調
用 FragmentTransaction 的 remove()、replace()方法將碎片從活動中移除,但有在事務提 交之前調用 addToBackStack()方法,這時的碎片也會進入到停止狀態。總的來說,進入 停止狀態的碎片對用戶來說是完全不可見的,有可能會被系統回收。
4. 銷毀狀態 碎片總是依附於活動而存在的,因此當活動被銷毀時,與它相關聯的碎片就會進入
到銷毀狀態。或者通過調用 FragmentTransaction 的 remove()、replace()方法將碎片從活 動中移除,但在事務提交之前並沒有調用 addToBackStack()方法,這時的碎片也會進入 到銷毀狀態。 結合之前的活動狀態,相信你理解起來應該毫不費力吧。同樣地,Fragment 類中也提供
了一系列的回調方法,以覆蓋碎片生命周期的每個環節。其中,活動中有的回調方法,碎片 中幾乎都有,不過碎片還提供了一些附加的回調方法,那我們就重點來看下這幾個回調。
1. onAttach()
當碎片和活動建立關聯的時候調用。
2. onCreateView()
為碎片創建視圖(加載布局)時調用。
3. onActivityCreated()
確保與碎片相關聯的活動一定已經創建完畢的時候調用。
4. onDestroyView()
當與碎片關聯的視圖被移除的時候調用。
5. onDetach()
當碎片和活動解除關聯的時候調用。 碎片完整的生命周期示意圖可參考圖 4.8,圖片源自 Android 官網。

圖 4.8
4.3.2 體驗碎片的生命周期
為了讓你能夠更加直觀地體驗碎片的生命周期,我們還是通過一個例子來實踐一下。例 子很簡單,仍然是在 FragmentTest 項目的基礎上改動的。
修改 RightFragment 中的代碼,如下所示:
public class RightFragment extends Fragment {
public static final String TAG = "RightFragment";
@Override
public void onAttach(Activity activity) {
super.onAttach(activity); Log.d(TAG, "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); Log.d(TAG, "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() { super.onStart(); Log.d(TAG, "onStart");
}
@Override
public void onResume() { super.onResume(); Log.d(TAG, "onResume");
}
@Override
public void onPause() { super.onPause(); Log.d(TAG, "onPause");
}
@Override
public void onStop() { super.onStop(); Log.d(TAG, "onStop");
}
@Override
public void onDestroyView() { super.onDestroyView(); Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy");
}
@Override
public void onDetach() { super.onDetach(); Log.d(TAG, "onDetach");
}
}
我們在 RightFragment 中的每一個回調方法里都加入了打印日志的代碼,然后重新運行 程序,這時觀察 LogCat 中的打印信息,如圖 4.9 所示。

圖 4.9
可以看到,當 RightFragment 第一次被加載到屏幕上時,會依次執行 onAttach() 、 onCreate() 、onCreateView() 、onActivityCreated() 、onStart() 和 onResume() 方法。然后點擊 LeftFragment 中的按鈕,此時打印信息如圖 4.10 所示。

圖 4.10
由於 AnotherRightFragment 替換了 RightFragment,此時的 RightFragment 進入了停止狀 態,因此 onPause()、onStop()和 onDestroyView()方法會得到執行。當然如果在替換的時候沒 有調用 addToBackStack() 方法,此時的 RightFragment 就會進入銷毀狀態,onDestroy() 和 onDetach()方法就會得到執行。
接着按下 Back 鍵,RightFragment 會重新回到屏幕,打印信息如圖 4.11 所示。

圖 4.11
由 於 RightFragment 重 新 回 到 了 運 行 狀 態 , 因 此 onActivityCreated() 、 onStart() 和 onResume()方法會得到執行。注意此時 onCreate()和 onCreateView()方法並不會執行,因為我 們借助了 addToBackStack()方法使得 RightFragment 和它的視圖並沒有銷毀。
再次按下 Back 鍵退出程序,打印信息如圖 4.12 所示。

圖 4.12
依次會執行 onPause()、onStop()、onDestroyView()、onDestroy()和 onDetach()方法,最 終將活動和碎片一起銷毀。這樣碎片完整的生命周期你也體驗了一遍,是不是理解得更加深 刻了?
另外值得一提的是,在碎片中你也是可以通過 onSaveInstanceState()方法來保存數據的, 因為進入停止狀態的碎片有可能在系統內存不足的時候被回收。保存下來的數據在 onCreate()、onCreateView()和 onActivityCreated()這三個方法中你都可以重新得到,它們都含 有一個 Bundle 類型的 savedInstanceState 參數。
