2012-05-25 42 views
4

以及我們最熟悉的模式:Android應用程序生命週期和singelton

public class MySingeltone { 

    public String mSomeReferenceTypeData; 
    public int mSomeValueTypeData; 

    private static MySingeltone mInstance; 

    private MySingeltone() { 

    } 

    public static MySingeltone getInstance() { 
     if (mInstance == null) { 
      mInstance = new MySingeltone(); 
     } 

     return mInstance; 
    } 
} 

我的問題是,我最近發現mInstance做活動後不等於空利用他被破壞,或當整個應用程序假設是條款,例如:

public class SomeActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     MySingeltone mySingeltone = MySingeltone.getInstance(); 
     mySingeltone.mSomeReferenceTypeData = "some value"; 
    } 
} 

關閉整個應用程序運行的活動啓動後,當「SomeActivity」下一次(10秒後說..)的mInstance仍持有相同的參考,與在他的領域相同的價值。

它爲什麼會發生?

我錯過了什麼?

當Android垃圾收集靜態成員屬於應用程序?

+0

你在哪裏查看單例是同一個實例? –

+0

@Jazzy Josh:你可以簡單地通過在設置新值之前獲取值來看到它。在我的例子中,它將介於getInstance方法和下一行之間。只需要檢查它不等於空,因爲首先啓動的值將仍然爲空。 –

+0

我特別指的是在應用程序中的位置。如果你的Activity沒有被殺死,那麼你將從onStop轉到onRestart和onStart,而不是通過onDestroy並被殺死,你的Singleton仍然會活着。 –

回答

5

由於「mInstance」是一個靜態變量,它在關閉應用程序時不會爲空。關閉應用程序並不意味着您的應用程序被破壞。

也沒有關閉您的Android應用程序的概念。如果你離開你的應用程序,它不會同時被銷燬。 Android OS在內部處理它何時關閉應用程序,當它不再被使用時。如果android在決定銷燬應用程序時內存不足,那麼這個靜態變量也會變爲null。

+3

這個答案是錯誤的,如果內存已滿並且android os決定撤出他的應用程序,那麼這個變量將爲空以及下次他嘗試使用它。 –

+0

感謝@OfekRon的更正。答案已更新。 – rizzz86

2

您無法控制Java對象何時變爲垃圾回收。當沒有更多(非循環)引用的對象時,對象就有資格進行垃圾回收。 使用Android,進一步,您無法控制活動何時從內存中移除。

+0

所以這意味着如果我期望我的singelton類在某些活動創建時爲空 - 我需要將它設置爲onDestroy()方法或類似的東西? –

+0

@Tan Kanel是的。但奇怪的是,你想摧毀一個單身人士,因爲單身人士應該代表一直存在的東西。也許你可能在你的單例中有一些open()/ close()/ isOpened()方法,或者它應該是一個Service。 –

+0

嗯,你是對的,這就是我正在做的,但我更多地問它的原理.. –

0

它爲什麼會發生?

我錯過了什麼?

當Android垃圾收集靜態成員屬於應用程序?

好吧,首先,正如其他人所說,由於android操作系統自己管理應用程序進程的生命週期,所以沒有關於Android的緊密應用程序概念。其次,你做了錯誤的測試 - 如果不是關閉所有的應用程序,而是做相反的事情 - 即通過啓動越來越多的應用程序來填充內存,那麼最終應用程序的內存將被清理以供使用其他應用程序,這包括所有靜態mebers以及實例成員!那麼,你會發現靜態變量會像你期望的那樣是NULL。

他們只是「懶洋洋地」清理內存,如果有足夠的內存,那麼你的應用程序可能永遠不會清理乾淨。

實際上,沒有辦法繞過它,據我所知,沒有辦法grauntee一個對象不會在任何時候從設備內存清理。在某些情況下會導致不良行爲。例如,如果單身人士對其創作進行了大量處理,那麼調用getInstance可能會導致用戶界面卡住,甚至會由於不負責任而導致應用程序崩潰。