【问题标题】:Difference between static reference and reference inside Application class?静态引用和应用程序类中的引用之间的区别?
【发布时间】:2013-11-09 02:34:49
【问题描述】:

假设我有一个类实例的引用,它没有对有问题的对象(如上下文、视图、...)的任何直接/间接引用。在静态引用中使用此引用与在扩展Application 类的类中使用它有什么区别?

我的意思是,在这两种方式中,只有当进程被终止(或者没有对它的引用时)才会释放被引用的对象,对吧?使用多个进程可能会有区别?

【问题讨论】:

    标签: android


    【解决方案1】:

    一个细微的区别是Garbage Collector 将首先销毁绑定在Activities(或Services)中的静态引用,以防内存严重不足,如果它是在静态引用和内部引用之间进行选择的情况下Application 班级。之所以会出现这种情况,是因为当Activity(或Service)被销毁时,它会留下没有引用的静态变量(如果它们除了上述引用之外没有其他引用),因此它们可以被GC收集。即使 VM 重新初始化 Activity(或 Service),这些静态引用也会采用初始值,丢失可能已经发生的任何更新。作为一般经验法则,如果您想确保静态变量是持久的:

    1. 不要从Activities(或Services)引用它们,因为它们可能会在内存不足的情况下被破坏。
    2. 从活动或服务中引用它们,但处理它们被手动销毁的情况(例如,使用 Android 的 onSavedInsanceState 方法),就像使用非静态引用一样。

    编辑以下解释为什么会发生这种情况:

    静态引用绑定到类的类加载器 首先初始化它们。这意味着如果一个静态变量 在任何类内部都已由活动初始化,当 活动被破坏,它的类也可能被卸载,所以 变量变得未初始化。而如果变量被初始化 通过应用程序类,它的生命与应用程序相同 过程,所以我们确信它永远不会再次未初始化。 这就是为什么我选择初始化所有单例 MyApplication 类。

    在这个link中找到。

    【讨论】:

    • 真的吗?你能提供一个你在哪里读过的链接吗?另外,为什么会发生?这与它在 java “world” 上的工作方式完全相反吗?
    • 我明白了。如果类的java文件有静态引用怎么办?我的意思是,如果它不在活动类中,而是在其自身?这样的引用是否也有可能是空的?另外,google 有没有关于这个问题的更官方的文字?
    • 我无法给出明确的答案,但我相信会发生与我的答案中描述的相同的行为,因为应用程序上下文引用的生命周期与应用程序的生命周期相同,但GC 是可能的在内存使用频繁时清除静态类中的静态引用。我找不到谷歌描述这个问题的更正式的文件。我刚刚提到了这个问题,因为我听到很多程序员抱怨有时会清除他们的静态引用,我发现记住这一点很有用。毕竟这有一个逻辑解释。
    • 我不是说静态类。我的意思是与 android 无关的普通公共类,例如,一个里面有一个 int 的类。如果在这个类中我有对同一个类的实例的引用,那么同样的奇怪规则也将适用于它(意味着引用可能在某些时候为空)?
    • 我相信这是另一回事,我不确定是否适用相同的规则,因为您将拥有该类的一个实例,并且该实例的引用所在的位置定义了该类的寿命实例,换句话说,该类的实例取决于保存引用的实例或静态类。例如,如果您在 Activity 中有该引用,则该实例的生命周期取决于 Activity 的生命周期。
    【解决方案2】:

    我相信@Angelo 在另一个答案中引用的article 是非常错误的(至少可以这么说)并引起了很多混乱:android 中的类是基于每个进程而不是基于每个类卸载的。也就是说,如果您的应用程序被杀死 并且 类被卸载,那么您将失去 所有 静态状态 - 如果不是。这就是我对@fadden 的回答的看法:

    Is it still the case that Android never unloads classes?

    Android: When do classes get unloaded by the system?

    现在你的问题有点含糊......静态引用与非静态引用不同,无论它在哪里使用。如果您的意思是这两个变量都是静态的,那么它们在活动、应用程序或任何实例中都没有区别 - 每当加载类并且变量取某个值时,它们将保持不变,直到类被卸载。不确定在卸载类时是否有指定的顺序 - 或者这是否重要。

    【讨论】:

    • 不,我的问题是基于这样一个事实,即您可以从“应用程序”类扩展,并将变量放在那里,而不是把它们放在静态引用中。可能的原因是这个类只有一个真实的实例,并且它存在于单个进程中,直到进程被终止,就像静态引用一样。
    • @androiddeveloper: “这个类只有一个真正的 (??) 实例,它只存在于一个进程中,直到进程被杀死” --> 我是对此我不确定,我继续asked
    • 我只有一次在发生其他事情后调用了应用程序的 onCreate(我认为是广播接收器,但我不确定)。但是,据我所知,每个进程只有一个 Application 类的真实实例。我所说的“真实”是指因为您始终可以执行“new App()”并使用它,但 Android 只会将它自己创建并调用其“onCreate()”方法的实例用于您的应用程序。
    • 可能是内容提供者(请参阅docs) - 但是“单例”属性记录在哪里last 销毁的保证在哪里?
    • 是的,我认为它是一个内容提供商。甚至文档也这么说:developer.android.com/reference/android/app/…。在那里你还可以看到一些关于应用程序作为单例的线索(因为它是静态引用的替代品)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多