【问题标题】:Static Context Warning静态上下文警告
【发布时间】:2016-09-29 14:54:38
【问题描述】:

现在,当类包含静态 Context 对象时,Android Studio 会显示警告。它说这会导致内存泄漏。但是,我注意到这也是在 android 库中完成的。例如,LocalBroacastManager 类有一个静态实例,它包含一个 context 对象。

那么这作为内存泄漏有多严重?

我有一个在后台运行的单例地理围栏类,并将boolean 保存到sharedPreferences,指示用户是否在地理围栏中。为了保存首选项,我需要一个context 对象,但由于该方法是一个被覆盖的方法,我无法传入上下文对象。

如果没有context 实例变量,如何实现?

【问题讨论】:

    标签: java android performance android-studio memory-leaks


    【解决方案1】:

    这是你能遇到的最糟糕的情况。假设您有一个活动,并将其存储为静态上下文。除非您在活动完成时将其清空,否则您现在已经泄漏了整个活动。这意味着活动持有的每个变量都被泄露,包括整个视图层次结构。它基本上阻止了该上下文中的任何内容释放。

    最好的办法不是存储上下文,而是将其作为参数传递给需要它的函数。如果您必须存储上下文,请不要将其设为静态。只要在活动完成后框架中没有任何东西继续持有对该对象的引用,非静态变量就不会泄漏它。

    如果您绝对必须使用静态上下文,请将其设为应用程序上下文。该文件在您的应用程序的整个长度内都有效,因此不会真正泄露。

    【讨论】:

      【解决方案2】:

      应该很少使用静态,尤其是在 Android 中。使用静态有很多方法和原因,但在 90% 的情况下,这只是对它们的滥用。

      将上下文保持为静态变量是一个很大的禁忌。想象以下场景:

      1. 您从活动 A 转到活动 B。
      2. 在活动 B 中,您将活动 B 引用作为静态上下文保留在某处。
      3. 您返回到活动 A。活动 B 应该被销毁,而是保留,因为您保留了对它的静态引用。
      4. 现在您再次从 A 转到 B,等等 - 您有两个 B 实例:您看到的一个,另一个作为静态上下文保存。

      您可能永远不会拥有同一活动的两个实例。这可能会导致很多问题。

      现在,我知道很多开发人员(甚至是制作库的开发人员)时不时会犯错误并使用反模式,因此您不应盲目依赖在他人代码中看到的实践/模式。该死,我什至在 Google 开发人员编写的东西中看到了很多垃圾代码。

      如果您真的需要一个单例(不是单例模式(大写 S)),而是某个类的单个实例,如果您不想使用 Dagger 等库,您可以在 Application 类中实例化该类,然后从任何你想要的地方引用它。

      【讨论】:

      • 实际上,现在大多数人都认为 Application 对象作为单例持有者已经过时了。与使用静态相比,它没有任何优势。使用静态创建单例没有问题,但不应该用于保存上下文。
      • 将对象保存为静态并以这种方式访问​​它们意味着共享状态,这是需要避免的。此外,由单例模式制作的旧单例无法继承和扩展。如果您只需要一个类的实例 - 只创建一个实例并使用 IoC 使其在需要的任何地方可用。我不确定为什么它是不合时宜的,Application 类是单例的,几乎是类/依赖关系树中的顶级类,类似于普通 Java 应用程序中持有 main() 方法的类,它是实例化 ssingleton 的最佳候选者.
      猜你喜欢
      • 2018-04-02
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多