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

时间:2012-04-21 11:29:41

标签: android process static android-context

我知道在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;
    }
}

5 个答案:

答案 0 :(得分:28)

  

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

目前,是的,它似乎是安全的,但我不会getAppContext()返回Context,而是返回App或{{1} }。

话虽如此,核心Android团队首先没有以这种方式设置它的事实表明,可能存在我们不知道的隐藏问题,或者将来这种方法可能会引入问题。

正如这句话的首字母缩写词YMMV。 : - )


修改

  

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

我不知道你这里的“安全”是什么意思。

  

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

如果你使用多个过程,你应该被鳟鱼打耳光。但是,是的,您应该为每个进程获得不同的Application个实例。

答案 1 :(得分:7)

应该是安全的。此外,API docs中的以下注释可能与您相关:

  

通常不需要继承Application。在大多数情况下,   静态单例可以在更模块化的情况下提供相同的功能   办法。如果您的单身人士需要全局上下文(例如注册   广播接收器),可以给出一个检索它的功能   内部使用Context.getApplicationContext()时的上下文   首先构建单身人士。

答案 2 :(得分:4)

Application#onCreate()中执行此操作是安全的,因为Application是在任何活动之前创建的。如果您的应用在后台被杀,则会重新创建Application实例,并在任何活动运行之前设置您的全局。

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

  1. 在活动A中设置全局
  2. 导航至活动B
  3. App进入后台
  4. 框架杀死了应用和流程
  5. 应用已恢复
  6. 框架创建活动B. 在您导航回到它们之前,不会创建backstack中的活动,因此未设置全局!
  7. 活动B尝试使用global,并且繁荣...... NullPointerException

答案 3 :(得分:1)

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

"这是泄漏(也打破了瞬间运行)。"

因此,随着Instant Run的推出,我们遇到了Android开发人员不打算保存静态变量的情况。虽然即时运行尚未列入我的议程,但有必要知道有一个特定的例子,它不仅是不良做法,而是识别出错误的用例。

答案 4 :(得分:0)

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

  

请勿将Android上下文类放在静态字段中;这是一个   内存泄漏,还会中断即时运行。

     

静态字段将泄漏上下文。

     

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

     

如果该外部类是例如Fragment或Activity,则此   引用意味着长时间运行的处理程序/加载程序/任务将保存一个   引用活动以防止其成为垃圾   集。同样,直接引用活动和   这些运行时间较长的实例中的碎片可能会导致泄漏。

     

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