和活動一樣,碎片也有自己的生命週期,並且它和活動的生命週期實在是太像了,我相 信你很快就能學會,下面我們馬上就來看一下。
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 引數。