Android:维护全局应用程序状态

4
Android应用程序状态文档: 通常情况下,没有必要子类化Application。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能[即维护全局应用程序状态]。如果您的单例需要全局上下文(例如注册广播接收器),则检索它的函数可以给定一个Context,该Context在首次构建单例时内部使用Context.getApplicationContext()。 我的请求是:您能解释并提供实现上述建议以维护全局状态的代码示例吗? 请注意,已经有一个建议建议子类化Application: 如何在Android中声明全局变量? 谢谢。
2个回答

7

对于ApplicationState中上下文的内容,需要更正StinePike的答案。在发布的代码中,应用程序状态传递的上下文被保留。如果传递的上下文是活动或类似单元,则活动将被泄漏并防止进行垃圾回收。

Android Application类的文档指出,当首次构建单例时,应“内部使用Context.getApplicationContext()”。

public class ApplicationState {
    private Context applicationContext;
    private static ApplicationState instance;

    private ApplicationState(Context context) {
        this.applicationContext = context.getApplicationContext();
    }

    public static ApplicationState getInstance(Context context) {
        if(instance == null) {
            instance = new ApplicationState(context);
        }
        return instance;
    }
}

请您简要解释一下 Context.getApplicationContext() API 文档中所说的内容:“如果从此处返回的 Context 中使用,接收器将被注册到与您的应用程序相关联的全局状态。因此,它永远不会为您取消注册。如果接收器与静态数据而非特定组件相关联,则这是必需的。但是,如果您忘记取消注册、解绑等操作,则在其他地方使用 ApplicationContext 很容易导致严重的泄漏问题。” - Antonio Sesto
1
@AntonioSesto API文档涉及到两种情况。在第一种情况下,它指的是直接使用上下文对象(例如activity)来注册一个接收器,如activity.registerReceiver(...),并指出在活动销毁完成之前应该取消注册接收器。它还指出,如果您未能取消注册接收器,框架将自动执行此操作,从而防止已注册的接收器和引用泄漏。 - Ryan Thomas
1
@AntonioSesto 在第二种情况中,你引用的API文档是指使用应用程序上下文,例如activity.getApplicationContext().registerReceiver(...),在这种情况下,您将可以访问应用程序的“全局状态”中的静态数据,但是注册的接收器不会自动清除任何点,这意味着开发人员需要确保他们不会意外创建允许注册接收器或类似对象创建泄漏的情况。 - Ryan Thomas

6

如果我没错的话,你想要保存全局变量但不想扩展应用程序(Application)。如果是这样,你可以做两件事情:

如果你不需要任何上下文(context),那么你可以简单地使用一个带有静态成员的类,像这样:

public class ApplicationState {
    public static boolean get() {
        return b;
    }

    public static void set(boolean a) {
        b = a;
    }

    private static boolean b;
}

如果您需要上下文但又不想扩展应用程序,您可以使用

Public class ApplicationState {
    private Context context;
    private static ApplicationState instance;

    private ApplicationState(Context context) {
        this.context = context;


    public static ApplicationState getInstance(Context context) {
        if (instance == null) {
            instance = new ApplicationState(context);
        }
        return instance;
    }

    public void someMethod(){}
}

因此,您可以像这样调用某些方法ApplicationState.getInstance(context).somemethod();


正如Ryan Thomas所指出的,使用Context.getApplicationContext()而不是传递的context是正确的。 - Octavian
作为建议1的更安全的措施:您可以将其标记为私有构造函数,这样就无法实例化它。 - Punith Raj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接