2009-12-22 104 views
88

我正在創建事件搜索應用程序,我們從一個屏幕中設置搜索條件並將其填充到另一個屏幕中,然後用戶可以從第3個屏幕編輯搜索條件並轉到第4個屏幕。Android靜態對象生命週期

爲了實現上述任務,我使用了記住應用程序周圍值的靜態對象,我不需要額外做任何事情。

但是我怕如果關於android中的靜態對象生命週期如果內存不足發現android刪除靜態對象???

由於android支持多任務處理,如果用戶切換到另一個應用程序,並且當用戶回來時應用程序開始動作瘋狂,那麼當多任務時靜態對象會被刪除嗎?任何想法 ??並建議通過單例方法保持靜態對象是更好的方法?

回答

215

讓我們從一點背景開始:當你啓動一個應用程序時會發生什麼?
操作系統啓動一個進程併爲其分配一個唯一的進程ID並分配進程表。進程啓動一個DVM實例(Dalvik VM);每個應用程序在DVM中運行。
一個DVM管理類加載卸載,實例生命週期,GC等。

靜態變量的生存期:靜態變量在類被JVM加載並在類卸載時死亡時出現。

因此,如果您創建一個Android應用程序,並初始化靜態變量,它會留在JVM中,直到發生下列情況之一:
1類被卸載
2. JVM關閉
3。該進程死亡

請注意,當您切換到另一個應用程序的其他活動時,靜態變量的值將會持續存在,並且上述三個操作都不會發生。如果上述三種情況發生,靜態將失去其價值。

您可以用幾行代碼測試:

  1. 打印未初始化的靜態在活動的onCreate - >應打印空
  2. 初始化靜態。打印它 - >值將爲非空
  3. 點擊後退按鈕並進入主屏幕。注意:主屏幕是另一項活動。
  4. 再次啓動您的活動 - >靜態變量將爲非空
  5. 從DDMS(設備窗口中的停止按鈕)中終止您的應用程序進程。
  6. 重新啓動您的活動 - >靜態將具有空值。

希望有所幫助。

+11

這是一個很好的解釋,任何Android開發者都應該閱讀。 – 2012-09-12 00:49:31

+1

我想知道爲什麼我失去應用程序對象中的字段值,如果它不是靜態的,例如我開始新的活動時,例如我在應用程序對象中聲明瞭可變的當前頁面,並且當我打開新的活動時它的值總是返回到零 – 2013-02-14 11:12:42

+0

super.onRestoreInstanceState(savedInstanceState);即使它們是靜態的,我也失去了我的變量,這是什麼問題? – 2013-02-14 11:18:09

14

那麼,Singleton模式也是基於使用靜態變量,所以實際上你會處於相同的位置。雖然靜態方法可能在大多數情況下都有效,但在某些情況下,當內存已滿並且另一個活動在應用程序移至其下一個屏幕之前佔用前臺時,您的活動進程可能會被終止,並且會丟失靜態值。 但是Android提供了國家之間持續存在的值或發送它們如的幾個選項:使用意向

  • ,你可以沿着 從活動通過你的搜索條件 活動(類似於網頁的HTTP 請求)
  • 使用應用程序的喜好,你 可以保存值,並在使用SQLite數據庫需要它們
  • 活動檢索 他們,你可以堅持 他們在一個表和檢索 他們後來
  • ,如果你只是需要保存活動 狀態,這樣在重新啓動時,場 得到填補,具有以前 選擇的值,可以實現 的的onSaveInstanceState()活動 方法 - 請注意,這不是 推薦在活動 之間持續的狀態。

您可以通過查看谷歌代碼aegis-shield source code tree或其他開源的Android應用程序獲取偏好,意圖和SQLite數據庫的使用的一些代碼示例。

3

經過一番研究,事實證明,使用應用程序存儲單身並沒有很大的想法,除非你準備創建它:

Don't store data in the application object

因此而the accepted answer在技術上是正確的,它不提供所有信息。

正如上面的鏈接所暗示的,如果您確實想堅持使用該模型,您需要準備好檢查null並重新創建數據(如果可能)。

1

@ r1k0就在這裏。將數據存儲在類的靜態字段中將不會在應用程序進程殺死並重新啓動時自行保留。當Android需要內存時,Android會常常殺死進程(運行應用程序)。

每Android的文檔:Activity state and ejection from memory

系統永遠不會直接殺死的活動。相反,它會殺死活動運行的 進程,不僅會破壞活動 ,還會破壞進程中運行的其他所有進程。

您可以使用以下方法保存和恢復基元的狀態以及Serializable和Parcelable對象。這些會在正常的活動生命週期中自動調用。

protected void onSaveInstanceState(Bundle state) {} 
protected void onRestoreInstanceState(Bundle savedInstanceState){} 

所以,如果你有一個只有靜態變量的一類,可以節省每個字段的onSaveInstanceState中()狀態,並在onRestoreInstanceState恢復它們()。當Android終止您的應用程序運行的進程時,變量的狀態將被保存,並且當Android恢復您的應用程序時,這些值將以與以前相同的狀態在內存中恢復。