2016-09-29 69 views
0

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

那么作为内存泄漏有多糟?

我有一个singleton geofencing类,它在后台运行,并将boolean保存到sharedPreferences,指示用户是否在geofence中。为了保存首选项,我需要一个context对象,但由于该方法是重写的方法,因此我无法传递上下文对象。

如何在不使用context实例变量的情况下完成此任务?

回答

2

它关于你可以有最糟糕的。让我们说你有一个Activity,并把它作为一个静态的Context来存储。除非您在活动结束时将其清空,否则您现在已经泄露了整个活动。这意味着活动所持有的每个变量都会泄露,包括整个视图层次结构。它基本上阻止了这种情况下的任何事情的解放。

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

如果您绝对必须使用静态上下文,请将其设置为应用程序上下文。这是一个在你的应用程序的长度有效,所以它不能真正泄漏。

1

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

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

  1. 您从一个活动到活动B.
  2. 而在b活动你保持活性B参考静态语境地方。
  3. 你回到活动A.活动B应该被销毁,但是它被保留下来,因为你保留了对它的静态引用。
  4. 现在你再次从A等到B,你有两个B实例:一个是你看到的,另一个是静态上下文。

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

现在,我意识到许多开发人员(甚至是制作库的人)偶尔会犯错并使用反模式,所以您不应该盲目地依赖别人代码中看到的练习/模式。地狱,我甚至在谷歌开发者写的东西中看到了很多垃圾代码。如果你真的需要一个单例(不是单例模式(大写S)),而是某个类的单个实例,如果你不想使用像Dagger这样的库,那么你可以在你的Application类中实例化这个类,然后从任何你想要的地方引用它。

+0

实际上,大多数人发现应用程序对象作为单身持有者最近已经是一个时代错误。它不会优于使用静态。使用静态来创建单例没有问题,但不应该用来保存上下文。 –

+0

将objets保存为静态并以这种方式访问​​它们意味着共享状态,这是避免的。另外,单身模式制作的旧单身不能被继承和扩展。如果只需要一个类的实例 - 只需创建一个实例并使用IoC,就可以在需要的地方使用该实例。我不确定为什么它是不合时宜的,Application类是单类和几乎在类/依赖关系树中的顶级类,就像在普通Java应用程序中持有main()方法的类一样,可以成为实例化ssingleton的根位。 – SadClown