正如到目前為止所描述的,如果你運行這個應用並在運行時旋轉屏幕,你會發現每當屏幕旋轉時,顯示的日期會發生變化。旋轉屏幕導致應用被銷毀並重新創建。每次旋轉屏幕時,這個示例應用的所有狀態都會丟失。
注意:這是測試你的應用的一種非常好的方式。按下Ctrl+F11鍵會使模擬器旋轉90°。為了響應這個旋轉操作,Android啟動了幾乎在整個生命週期都會一直存在的一個活動。通過這個按鍵,你的測試可以覆蓋到大部分的代碼!
在這個簡單的示例應用中,狀態丟失沒有什麼影響。但是,對於實際應用,一般不允許丟失狀態。例如,在查看某個Web頁面時,如果旋轉手機為橫向模式後導致瀏覽器回到主頁將會顯得非常煩人。
可以對應用執行兩個小小的修改以使其能夠保存住狀態。首先,覆蓋DateTime fragment的方法onSaveInstanceState以保存其狀態。其次,改變onCreate方法以恢復之前保存的狀態。正如在P84「活動生命週期」一節中所講的,當掛起一個fragment時,Android框架會為前一個方法提供Bundle對象。當重新構建被掛起的fragment副本時,它會提供該bundle給onCreate方法。
以下是為了支持狀態保存所修改的兩個方法:
@Override public void onCreate(Bundle state) { super.onCreate(state); if (null != state) { time = state.getString(TAG_DATE_TIME); } if (null == time) { time = new SimpleDateFormat("d MMM yyyy HH:mm:ss") .format(new Date); } } @Override public void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); state.putString(TAG_DATE_TIME, time); }
就是這麼簡單。對於這個版本的程序,在其生命週期內運行它不會再發生狀態丟失。順便提一下,因為變量time(一般來說,對於任何的fragment狀態)是在onCreate方法中初始化的,所以不能把它聲明為final類型。這使得使用構造函數初始化fragment狀態沒有太大意義,這也和之前提到的Android開發文檔建議的Fragment子類不要有任何顯式的構造函數一致。
Android開發文檔介紹了完整的fragment生命週期。然而,還有一個生命週期回調方法值得特別關註:onPause。onPause方法之所以重要是因為它在活動中很重要。應用要在Android環境中良好工作,當該應用不可見時,就不應該執行操作(佔用CPU、消耗電池等)。當某個fragment變得不可見時,Android環境會調用這個fragment的onPause方法。在這個方法中,fragment應該釋放其持有的所有資源,中止它所啟動的任何長時間運行的進程等。