50

我知道在 Android 上使用静态变量是非常危险的,尤其是当您将它们引用到活动时。但是,如果我有一个扩展 Application 的类(我们称这个类为“App”),那么引用这个类的实例是否安全?

如果是这样,任何其他类对应用程序上下文有任何类型的引用是否也是安全的?我的意思是,如果我在任何类型的类中都引用了应用程序上下文,会不会出现内存泄漏?

目的是无论我在哪个范围内,我总能获得对应用程序上下文的引用。我认为这是安全的,因为如果系统关闭应用程序,静态变量也会消失,直到下次应用程序再次启动,这将再次初始化静态变量。

另外,这并不重要,但是如果我使用多个进程,我会在每个进程上获得对 App 类的完全不同的引用吗?

作为代码示例,这就是我的想法:

public class App extends Application
{
    private static Context _appContext;

    @Override
    public void onCreate()
    {
        super.onCreate();
        _appContext = this;
    }

    public static Context getAppContext()
    {
        return _appContext;
    }
}
4

5 回答 5

31

将应用程序上下文保存到静态变量是否安全?

目前,是的,它似乎是安全的,虽然我不会有getAppContext()return Context,而是 return Appor Application

话虽如此,核心 Android 团队一开始并没有这样设置,这表明可能存在我们不知道的隐藏问题,或者将来这种方法可能会带来问题。

俗话说,YMMV。:-)


编辑

如果是这样,任何其他类对应用程序上下文有任何类型的引用是否也是安全的?

我不知道您在这里所说的“安全”是什么意思。

但是如果我使用多个进程,我会在每个进程上获得对 App 类的完全不同的引用,对吧?

如果你使用多个进程,你应该被打上一条鳟鱼。但是,是的,您应该App为每个进程获得不同的实例。

于 2012-04-21T11:48:31.333 回答
9

它应该是安全的。API 文档中的以下注释也可能与您相关:

通常不需要子类化Application. 在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。如果您的单例需要全局上下文(例如注册广播接收器),则可以为检索它的函数提供一个上下文,该上下文Context.getApplicationContext()在首次构建单例时在内部使用。

于 2012-07-20T09:31:34.660 回答
5

这样做是安全的,Application#onCreate()因为它Application是在任何活动之前创建的。如果您的应用程序在后台Application被终止,则将重新创建实例并在任何活动运行之前设置您的全局。

请务必注意,您永远不应该从活动中设置全局变量。如果这样做,您的应用程序可能会以下列方式失败:

  1. 在活动 A 中设置全局
  2. 导航到活动 B
  3. 应用程序进入后台
  4. 框架杀死应用程序和进程
  5. 应用程序已恢复
  6. 框架创建活动 B. 在您导航回它们之前不会创建后台堆栈中的活动,因此未设置全局!
  7. 活动 B 尝试使用全局,并且繁荣...NullPointerException
于 2016-11-26T08:31:14.973 回答
1

当我整理令人讨厌的静态上下文时,Studio 弹出了有趣的评论:

“这是一个泄漏(也破坏了 Instant Run)。”

因此,随着 Instant Run 的推出,我们遇到了 Android 开发人员不打算保存静态变量的情况。虽然即时运行(尚未)在我的议程上,但知道有一个特定示例不仅是不好的做法,而且确定了错误的用例是很有用的。

于 2017-01-26T10:20:52.460 回答
-1

这是Context context;在 android-studio 中创建时的警告:

不要将 Android 上下文类放在静态字段中;这是内存泄漏,也会破坏 Instant Run。

静态字段会泄漏上下文。

非静态内部类具有对其外部类的隐式引用。

如果该外部类例如是 Fragment 或 Activity,则此引用意味着长时间运行的处理程序/加载程序/任务将持有对该 Activity 的引用,从而防止其被垃圾收集。同样,从这些运行时间较长的实例中直接对活动和片段的字段引用可能会导致泄漏。

ViewModel 类不应指向视图或非应用程序上下文。

于 2018-10-23T15:21:03.877 回答