2015-12-08 15 views
0

我創建了一個測試程序,看看Android的服務被正確地回收後存在。Android的服務實例繼續的onDestroy()和GC

我創建了一個服務,做一兩件事:拿着WeakReference的一個對象。這個想法是,在Service被銷燬並且GC被調用之後,WeakReference應該返回null。這裏是我的服務:

package com.example.test.serviceleaktest; 

import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.support.annotation.Nullable; 
import android.util.Log; 

import java.lang.ref.WeakReference; 


public class MyService extends Service { 

    public static WeakReference sWeakReference = new WeakReference(null); 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 
     sWeakReference = new WeakReference("data"); 
     Log.d("asdf", "MyService started"); 
     return START_NOT_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d("asdf", "MyService created"); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d("asdf", "MyService destroyed"); 
    } 

} 

我使用Context.startService()啓動服務並使用Context.stopService()來停止它。 LogCat確認onDestroy()被調用。然後,我做了GC(代碼LeakCanary複製):

Runtime.getRuntime().gc(); 
Thread.sleep(100); 
System.runFinalization(); 

在這一點上,我認爲sWeakReference.get()應該返回null,對不對?但它仍然返回分配的值。爲什麼?

+1

相信有一個隱含的硬參照字符串文字'「數據」''經由= sWeakReference新的WeakReference(「數據」)'。試試'sWeakReference = new WeakReference(new String(「data」))'。順便提一下這個字符串的弱引用的意圖是什麼? – cziemba

+0

謝謝。你是對的。 –

回答

0

這個想法是,在Service被銷燬並調用GC之後,WeakReference應該返回null。

您似乎誤解了WeakReference s,或者至少對我而言並不明顯,爲什麼您認爲您提供的代碼顯示出任何意外行爲。如果您創建一個WeakReference一些對象o,一段時間後,該GC確定o不強可到達,那麼GC將清除WeakReference

您正在創建一個WeakReference對象String,在您的源代碼中表示爲文字。如果Java使用該String的內部版本 - 它很可能會這樣做 - 那麼它可能會選擇將其視爲始終可以達到,以便引用對象永遠不會被清除。

因爲你說你要監視Service的清理,以及你目前的Service一個子類,我傾向於認爲你假設您正在監視創建WeakReference對象的清理。這不是它的工作方式。

如果你確實要監視Service的清理,那麼你想創建一個WeakReference服務對象。在您當前的代碼中,拼寫爲new WeakReference(this)

還應注意當對象不再是強可監測是的ReferenceQueue S中的目的。如果您創建一個ReferenceQueue並註冊WeakReference用它,那麼你可以觀看的弱引用入隊,而不是測試其目標是否被清除。