【问题标题】:Why to use Application subclass to hold global variables?为什么要使用 Application 子类来保存全局变量?
【发布时间】:2014-09-02 10:24:59
【问题描述】:

在我的应用程序中,我使用公共类 Globals 来保存我在整个应用程序中设置和获取的静态变量,只需通过 p.e. 引用它们即可。 Globals.someString:

public class Globals {
    // several static variables for use in the whole application:
    static String someString = "";
}

我的应用似乎运行良好。但现在我到处读到,全局变量应该定义在 Application 的子类或自己的单例类中,并由 setter 和 getter 访问。

我现在的问题是:我自己使用全局变量的方式有什么缺点吗?内存泄漏 p.e.还是其他问题?

【问题讨论】:

  • 全局变量不好......无论如何,除非您不将 Activity/Service 实例用作全局(或需要 Activity/Service 上下文的类,如 Views 实例等),否则全局之间没有区别类和应用程序子类 ...

标签: singleton global-variables android


【解决方案1】:

两部分答案:

第一部分:神话和理论

一般来说,在面向对象中,不建议使用静态全局变量,因为它非常不可控。这就是将 Singleton 与 getter/setter 一起使用的建议的来源。这是一个更可控的可管理环境。但是,如果您是应用程序的唯一开发人员并且不介意它。这确实是最佳实践,并不是应用正常运行所必需的。

子类 Application 或拥有自己的公共类,如果您使用的只是字符串、int 等,则没有区别。如果您正在初始化需要上下文的对象,则在互联网上将应用程序子类化是很常见的事情,例如数据库。我个人不太喜欢这种方法。它会减慢启动时间,并且可能会在内存中保留我并不真正需要的大对象。对于这些类型,我通常会进行惰性初始化,在其中我持有我的应用程序的 public static 引用,并且每当我调用时,例如,get() 内的 MyDatabase.get(); 我检查 if(instance==null) 然后使用公共初始化它可访问Application 对象。

如果您在 Android 中保留 Activity、Fragment 或 View 对象的静态引用,您总是会遇到内存问题。这些类很大,它们包含对其他大对象的引用,它们使用大量内存,这就是为什么框架有所有烦人的life-cyclesaveState。因此,它们可以在需要内存时被销毁,并在它们重新出现在屏幕上时重新构建。

第二部分:Android方式

在 Android 中只保留 public static 上的对象引用并不是非常可取的,因为它们将永远保留在内存中,而且手机不像具有 TB 级 RAM 的网络服务器。整个 Android 框架具有通过Bundle 对象传递和保存值(字符串、int 等)的非常完善的文档和稳定结构。您可以通过Intent 将这些捆绑包传递给活动,或通过setArguments(Bundle) 传递给Fragments,它们可用于使用onSavedInstanceState 方法保存当前状态。这些都是以 Android 方式做事的明智之举。而且它还有助于促进班级分离,即使对于小型项目来说,你听起来可能需要做很多工作,但对于大型项目来说,这是保持结构和组织的方法之一。

【讨论】:

  • 感谢您非常详细的回答。但是“公共静态将永远留在内存中”是什么意思?当应用程序关闭时它们还在内存中吗?如果再次打开应用程序,这些变量是否会有新的实例?
  • 对不起,也许我用错了。我的意思是,只要 JavaVirtualMachine (JVM) 正在运行,它们就会一直保留在内存中。请记住,“JVM 仍在运行”与“活动在前台”不同
  • 这并不能真正回答问题。如果 1 Application == 1 JVM 那么静态或单例是完全一样的。还是有别的?
【解决方案2】:

来自http://developer.android.com/guide/faq/framework.html

使数据可跨活动/服务访问的另一种方法是使用公共静态字段和/或方法。您可以从应用程序中的任何其他类访问这些静态字段。

来自http://developer.android.com/reference/android/app/Application.html

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

所以在我看来,使用静态变量是完全有效的。

【讨论】:

    猜你喜欢
    • 2014-08-04
    • 2023-03-22
    • 2014-02-24
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 2011-04-04
    相关资源
    最近更新 更多