Android Contesto di attività in classi statiche


Esempio

Spesso vorrai avvolgere alcune delle classi di Android in classi di utilità più facili da usare. Queste classi di utilità spesso richiedono un contesto per accedere al sistema operativo Android o alle risorse delle tue app. Un esempio comune di questo è un wrapper per la classe SharedPreferences. Per accedere alle preferenze condivise di Androids è necessario scrivere:

context.getSharedPreferences(prefsName, mode);

E quindi si può essere tentati di creare la seguente classe:

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);
    }
}

ora, se chiami init() con il tuo contesto di attività, LeakySharedPrefsWrapper manterrà un riferimento alla tua attività, impedendole di essere triturata.

Come evitare:

Quando si chiamano le funzioni di supporto statico, è possibile inviare il contesto dell'applicazione utilizzando context.getApplicationContext();

Quando si creano funzioni di supporto statiche, è possibile estrarre il contesto dell'applicazione dal contesto in cui viene fornito (Chiamare getApplicationContext () sul contesto dell'applicazione restituisce il contesto dell'applicazione). Quindi la correzione del nostro wrapper è semplice:

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

Se il contesto dell'applicazione non è appropriato per il tuo caso d'uso, puoi includere un parametro di contesto in ciascuna funzione di utilità, dovresti evitare di mantenere i riferimenti a questi parametri di contesto. In questo caso la soluzione sarebbe così:

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);
}