[Android] Service 中盡量不要使用 static 變數

APP 的 Activity 完全被關閉時 (多工列中完全不存在) 會把 static 變數全部清除,之後又觸發 Service 使用 static 變數就會踩到地雷

/*2014.4.11 Maple*/

我利用 public static 變數紀錄從檔案撈出 GCM 開關旗標,在每次與主機連線時就會傳遞相關資料給主機,

結果有些使用者會回傳 static 變數的初始值

我開始懷疑 Service 呼叫的 static 會消失或者與 Acticity 分開紀錄的可能性,但總覺得這問題很蠢......就沒 google ,

但我還是實測了各版本的 android 模擬器 ,在實測時一直使用返回鍵關閉 APP ,但實測結果一直都是同步且存在。

直到昨天意外發現使用返回鍵根本沒有完全關閉 APP !!! 再重新實測後發現很蠢的問題成真了.....

static 變數居然不 static !!! 

 

雖然在開發手冊中寫到可以使用 public static 變數作為 Activity 與 Service 之間的傳遞方式

A public static field/method

 

An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
 
但在 APP 的 Activity 完全被關閉時 (多工列中完全不存在)  static 變數就會被殺掉  (不論 public / prviate 的 static 都一樣)
若有指定變數初始值,呼叫時就會得到初始值
我並不是說從 設定->應用程式 裡面的關閉 APP ,而是看多工列即可判別
 
static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
 
 

至於為什麼我會強調 APP 的 Activity 完全被關閉時是指多工列中完全不存在

是因為在 APP 中曾經呼叫超過一個 Activity 時 ,使用 finish() 是不會完全關閉的,使用返回鍵也不會完全關閉

就算直接呼叫 System.exit(0) 或 android.os.Process.killProcess(android.os.Process.myPid()) 都是沒用的

(如果想完全關閉APP可以參考文章1文章2 文章3,但因為我沒有真的有此需求,所以沒試寫法)

在多工列還存有 APP 的狀況下,代表尚未完全關閉,static 的值還不會被殺掉,此時 Service/Activity 中都可以撈到共同的 static 值。

 

其他實測狀況:

在 APP 未開啟的狀態下,Service 一直撈取跟修改 static 值會一直存在,

之後再開啟 APP 撈取值會是 Service 最後設定的值,

但是 APP 的 Activity 被完全關閉時 static 又會被殺掉。

另外 Service class 裡設定的 private static 在 APP 的 Activity 完全關閉時也是會被殺掉