android - 在没有任何静态引用的情况下使用上下文

标签 android design-patterns memory-leaks singleton

我正在尝试从 Singleton 类访问应用程序资源(具体来说是字符串资源)。作为 Singleton,此类不能持有对 Context 对象的任何引用(以防止内存泄漏)。当我在网上寻找其他实现时,我遇到了这两个实现:

  1. 在 Application 类中创建静态上下文并在整个应用程序中使用它。
  2. 将上下文作为参数传递给需要它的方法。

我不想使用第一个,因为它还使用了对 Context 对象的静态引用。我知道将它静态地放在 android 的 Application 类中是可以的,但它仍然看起来像 hack。

第二个实现是无用的,因为我没有任何可以传递给单例的 someOtherMethod 的上下文实例。

所以我想到了以下实现,在初始化单例实例时,我使我的单例抽象来覆盖其上下文需要的方法(例如,下面代码中的 getString(int resId))。

我很想知道这是否会导致内存泄漏?

我在哪里对这种方法感到困惑:

--> Overridden getString 中对上下文的引用是最终的。我不确定这是否会导致内存泄漏。

    public abstract class SingletonClass{

    .
    .
    .

    private static SingletonClass sInstance;

    private SingletonClass(Context paramContext) {
        // constructor code
    }

    public static SingletonClass getInstance(final Context context) {
        if (sInstance == null) {
            sInstance = new SingletonClass(context){
                @Override
                public String getString(int resId) {
                    return context.getString(resId);
                }
            };
        }
        return sInstance;
    }

    public abstract String getString(int resId);

    .
    .
    .

    private void someOtherMethod(){
        //uses above getString()
    }

    }

最佳答案

您的方法确实存在内存泄漏。传递给 getInstance 的第一个上下文永远不会被垃圾回收,因为您的匿名类持有对它的引用。 (并且有一个对匿名类的静态引用)。例如,如果您调用 getInstance(Activity),该 Activity 将保留在内存中,直到进程被终止!

幸运的是,有一个非常简单的修复方法可以消除内存泄漏。您可以安全地保留应用程序上下文 (context.getApplicationContext),它基本上是应用程序生命周期的单例上下文。

public static SingletonClass getInstance(Context c) {
    if (sInstance == null) {
        sInstance = new SingletonClass(c.getApplicationContext());
    }
    return sInstance;
}

关于android - 在没有任何静态引用的情况下使用上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41411969/

相关文章:

android - 识别并取消发送到 AlarmManager 的警报

android - Android 4.1/4.3/4.4 电子邮件应用程序中的 FileProvider 失败,列 '_data' 不存在

android - 从 ListView 传递到新 Activity 时出错

events - 为两个竞争对象建模的设计模式

iphone - NSString 潜在泄漏

Java.lang.OutOfMemoryError : unable to create new native thread -Linux 错误

android - 在 CardView 中使用 ConstraintLayout

php - 自注册组件/插件的设计模式

java - 使用新功能丰富类的设计模式

android - fragment 中的加载器 - fragment 会泄漏吗?