【问题标题】:Android - Google's Contradiction on Singleton PatternAndroid——谷歌对单例模式的矛盾
【发布时间】:2016-10-03 21:38:05
【问题描述】:

我已经阅读了一些关于 Android 中单例模式的使用以及它在保留上下文方面的缺点。事实上,当我实现以下代码时:

private static HttpManager sSingleton;
private Context mContext;

private HttpManager(Context context) {

    mContext = context;
}

public static synchronized HttpManager getInstance(Context context) {

    if (sSingleton == null) {
        sSingleton = new HttpManager(context);
    }

    return sSingleton;
}

Android Studio 向我显示以下警告:

不要将 Android 上下文类放在静态字段中(对 HttpManager 的静态引用,其中字段 mContext 指向 Context);这是内存泄漏,也会破坏 Instant Run。

但是,我可以看到单例实现并推荐 in this page of Android's docs

如果您的应用程序经常使用网络,那么设置一个可在您的应用程序生命周期内持续使用的 RequestQueue 实例可能是最有效的。您可以通过多种方式实现这一目标。推荐的方法是实现一个封装 RequestQueue 和其他 Volley 功能的单例类。

由于谷歌自相矛盾,有人可以指导我并在这一点上给我建议吗?

【问题讨论】:

  • 矛盾在哪里?
  • 没有矛盾。第一部分说您不应该将 Android 上下文类 放入单例中。第二部分没有提到将 那些 放入单例中。正确阅读文本并理解其内容非常重要。
  • ...that will last the lifetime of your app. 可能是指只要上下文对象还活着,对象(单例)就会活着(引用持有),这意味着应该使用应用程序上下文application.getApplicationContext()
  • @Luis - 如果您从 Google 的文档中复制代码并将其粘贴到 Google 的 IDE 中并收到警告,那就是矛盾了。

标签: java android design-patterns singleton


【解决方案1】:

因为谷歌自相矛盾

不,不是。

引用的 Lint 警告并没有抱怨创建单例。它抱怨创建持有对任意Context 的引用的单例,因为这可能类似于Activity。希望通过将 mContext = context 更改为 mContext = context.getApplicationContext(),您将摆脱该警告(尽管这可能仍然会破坏 Instant Run — 我无法对此发表评论)。

创建单例很好,只要您非常小心地这样做,以避免内存泄漏(例如,持有一个无限期的 static 引用到 Activity)。

【讨论】:

  • 这很奇怪,因为如果我使用您可以在该部分中找到的代码创建一个类(请参阅the link I mentioned before 中的 MySingleton 类),Android Studio 会向我显示该警告。因此,我推断当 Google 建议您按照他们建议不要这样做的方式设计课程时,它自相矛盾……我应用了您建议的更改,但警告仍在显示;无论如何,谢谢你的回答:)。
  • @NadiaCastelli:Lint 检查需要改进。见this issue
  • 太棒了!他们的文档与该警告之间的不一致让我感到困惑。非常感谢!
  • 所以如果我们忽略警告并提供this.getApplicationContext 作为上下文,那么实际上不会发生内存泄漏,对吧?
  • @Ozuf:正确。 Application 上下文是一个预先存在的单例。实际上,它是预先泄露的。你不能以某种方式进一步泄漏它。 :-)
【解决方案2】:

这确实是一个矛盾,因为在许多单例中你需要一个上下文。看看这篇文章,我现在正在使用这种方法来避免 android studio 中的警告:

Android Singleton with Global Context

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 2023-03-10
    • 2015-12-21
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    相关资源
    最近更新 更多