讀古今文學網 > Android程序設計:第2版 > 組件生命週期 >

組件生命週期

正如前面所描述的,Android應用和絕大多數操作系統的應用不同。在很多操作系統上,應用本身只有少量的代碼自己完成啟動和結束,而Android應用是管理的組件,有完整的生命週期。舉個例子,當應用啟動時,會調用Activity類的onCreate方法;當應用結束時,會調用onDestroy方法。組件生命週期有助於高效利用應用的內存(堆):它們支持保存和恢復整個進程的狀態,這樣Android系統就能夠運行比內存容量所能夠支持的更多的應用數量。

活動生命週期

最複雜的組件生命週期是活動的生命週期。這裡我們將通過圖表描述它,看看這些狀態變化在代碼層面是如何處理的。在圖3-4中,可以看到活動生命週期的狀態和狀態轉換。處理生命週期狀態轉換的核心因素在於選擇需要實現的那一種生命週期回調,並瞭解什麼時候執行這些回調。

圖3-4:活動生命週期狀態

在第10章中,我們將進一步深入探討這個話題。現在,我們來看看Activity類的兩種方法onSaveInstrance State和onCreate。在運行時調用第一種方法通知應用保存其狀態,調用第二種方法支持新的Activity實例恢復已經銷毀的活動生命週期的狀態。下面這段代碼摘自第10章,在第10章可以看到整個程序,包括所指向的成員變量:


@Override
protected void onSaveInstanceState(Bundle outState) {
      // Save instance-specific state
      outState.putString(\"answer\", state);
      super.onSaveInstanceState(outState);
      Log.i(TAG, \"onSaveInstanceState\");
}
  

當運行時系統要銷毀某個活動但是希望能夠在後期重新恢復其狀態時,會調用活動的onSaveInstanceState方法。這一點和執行狀態轉換的其他生命週期方法有顯著區別。舉個例子,如果一個活動顯式地結束了,其狀態就不再需要恢復,即使需要傳遞當前的已中斷狀態,調用其onPause方法。正如之前的代碼片段所示,在onSaveInstanceState方法中要做的是保存用戶在後期會用到的狀態,做到該活動的狀態銷毀和恢復對於後期使用是透明的:


@Override
      protected void onRestoreInstanceState(Bundle savedState) {
            super.onRestoreInstanceState(savedState);
            // Restore state; we know savedState is not null
            String answer = savedState.getString(\"answer\");
            // ...
            Log.i(TAG, \"onRestoreInstanceState\"
                    + (null == savedState ? \"\" : RESTORE) + \" \" + answer);
      }
  

當重新創建已經銷毀的活動時,會調用onRestoreInstanceState方法。因此,會運行該應用活動的一個新的實例。該應用活動的前一個實例中通過onSaveInstanceState方法所存儲的數據,會通過onRestoreInstanceState方法傳遞給新的實例。

你可能會認為活動有如此複雜的生命週期,並且對堆使用需求限制很嚴格,Android的活動生命週期在Android應用代碼中應該很清晰,需要花費很多時間和精力來滿足活動生命週期需求。然而,實際上並非如此。

在很多Android代碼中,尤其在小的Android實例中,很少實現生命週期回調功能。這是由於Activity父類會處理生命週期回調,即View類及其子類,並且保存它們的狀態,如圖3-5所示。這意味著在很多情況下,Android的View類會提供所有必要的用戶接口功能,Android應用不需要顯式處理大多數的生命週期回調。

圖3-5:保存用戶界面的狀態

這看起來確實很不錯,因為它使得Android編程變得簡單多了。你不需要編寫任何代碼,就可以輕鬆實現如圖3-5所示的內容。然而,它也存在不足,因為它會導致編程人員忽略活動的生命週期,直到某天發現自己的代碼存在一堆bug變得一團糟。這也是在這裡強調生命週期的原因,同樣也是在第10章要說明如何處理所有的生命週期回調並記錄日誌的原因。要充分意識到活動生命週期可能是在預防那些難以診斷的bug中所能做到的最重要的事情。

把軟件移植到Android

在這一章,我們瞭解到的Android應用架構和傳統的桌面應用架構有很大區別,甚至和大多數其他小型設備上的系統也很不一樣,包括iPhone、iPod Touch和iPad所使用的iOS操作系統。如果想實現Objective-C、C++或C#這些不同語言上方法之間的轉換,打算通過破壞Android應用架構並強制在Android應用中使用傳統的應用架構的方式來移植軟件,那麼結果可能會很悲劇。

如果你想把現有的軟件移植到Android系統中,首先要對該軟件進行分解:數據模型、用戶界面、主要的非交互式模塊和庫。這些模塊和庫到底是移植到Android應用模型中,還是對它們進行重新實現,這要根據具體情況來處理。Android確實和其他現代的可管理的應用運行環境及語言系統有相似之處。一旦對Android有了更深的理解,就可以看到Android平台和其他平台在架構上的異曲同工之處,在移植時也就能夠給出更好的實現方案。