靜態類中的活動上下文

通常,你會希望將一些 Android 類包含在更易於使用的實用程式類中。這些實用程式類通常需要上下文來訪問 Android 作業系統或應用程式的資源。一個常見的例子是 SharedPreferences 類的包裝器。要訪問 Androids 共享首選項,必須寫:

context.getSharedPreferences(prefsName, mode);

因此,可能會想要建立以下類:

public class LeakySharedPrefsWrapper
{
    private static Context sContext;

    public static void init(Context context)
    {
        sContext = context;
    }

    public int getInt(String name,int defValue)
    {
        return sContext.getSharedPreferences("a name", Context.MODE_PRIVATE).getInt(name,defValue);
    }
}

現在,如果你用你的活動上下文呼叫 init(),LeakySharedPrefsWrapper 將保留對你的活動的引用,防止它被垃圾收集。

如何避免:

呼叫靜態幫助函式時,可以使用 context.getApplicationContext(); 傳送應用程式上下文

建立靜態輔助函式時,可以從給定的上下文中提取應用程式上下文(在應用程式上下文中呼叫 getApplicationContext() 返回應用程式上下文)。所以對我們的包裝器的修復很簡單:

public static void init(Context context)
{
    sContext = context.getApplicationContext();
}

如果應用程式上下文不適合你的用例,則可以在每個實用程式函式中包含 Context 引數,應避免保留對這些上下文引數的引用。在這種情況下,解決方案看起來像這樣:

public int getInt(Context context,String name,int defValue)
{
    // do not keep a reference of context to avoid potential leaks.
    return context.getSharedPreferences("a name", Context.MODE_PRIVATE).getInt(name,defValue);
}