当前位置: 首页 > 面试题库 >

是否可以确保Activity类中的静态字段不会超过创建/销毁周期?

夏侯瑞
2023-03-14
问题内容

我经常遇到这样的问题,我必须在一个活动的几次调用之间保留状态(即经历几个onCreate()/
onDelete()周期)。不幸的是,Android对此的支持确实很差。

作为保存状态的简便方法,我认为由于类仅由类加载器加载一次,因此可以安全地将在活动的多个实例之间共享的临时数据存储在静态Bundle字段中。

但是,有时,当实例A创建静态捆绑并将其存储在其中,然后被销毁,并且实例B尝试从中读取时,静态字段突然变为NULL。

这不是意味着在活动经历创建/销毁周期时,类加载器已删除了该类并重新加载了该类吗?当 静态 字段之前引用对象时, 静态 字段如何突然变为NULL?


问题答案:

此答案的第一部分确实很旧-参见以下 正确 方法

您可以使用Application对象存储应用程序持久性对象。
此Android常见问题解答也讨论了此问题。

像这样:

public class MyApplication extends Application{
    private String thing = null;

    public String getThing(){
        return thing;
    }

    public void setThing( String thing ){
        this.thing = thing;
    }
}

public class MyActivity extends Activity {
    private MyApplication app;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        app = ((MyApplication)getApplication());

        String thing = app.getThing();
    }
}

正确的 方法

首次编写此答案时,活动生命周期的文档不如现在。阅读“活动”文档中的“
保存活动状态”部分可帮助我们了解Android如何希望我们保存状态。从本质上讲,活动在两种情况下开始:(1)作为新活动,(2)由于配置更改或由于内存压力而被销毁后重新创建活动。当您的活动由于是新活动而开始时,则saveInstanceState为null。否则不为null。如果为null,则您的活动应从头开始初始化。片段与“活动”非常相似,我在AnDevCon-14滑座上详细介绍了这个概念。您还可以查看示例代码
有关我的AnDevCon-14演示的更多信息。

重做我以前的示例将类似于下面的代码。我确实做了一些语义上的更改-
在第二个版本中,我假设字符串thing是特定于特定android任务中的活动的,在前面的示例中它是不明确的。如果您确实想为多个android任务保留相同的数据,那么最好还是使用Application对象或另一个单例。

public class MyActivity extends Activity {
    private static final String THING = "THING";

    private String thing;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState==null) {
            // First time here (since we last backed out at least)
            thing = initializeThing(); // somehow we init it
        } else {
            // Rehydrate this new instance of the Activity
            thing = savedInstanceState.getString(THING);
        }

        String thing = app.getThing();
    }

    protected void onSaveInstanceState(Bundle outState) {
        outState.putString(THING, thing);
    }
}


 类似资料:
  • 问题内容: 我想在PHP中创建一个静态类,并使其行为像在C#中一样,所以 在第一次调用类时会自动调用构造函数 无需实例化 这种东西… 问题答案: 您可以在PHP中拥有静态类,但它们不会自动调用构造函数(如果尝试调用,则会收到错误)。 因此,您必须创建一个函数并在每个方法中调用它:

  • 问题内容: 让我们考虑以下情况。有一个,有一个。子窗格将添加到父窗格。考虑到可以动态地添加和删除子窗格而没有任何限制和顺序的情况下,如何才能仅在可见子窗格的情况下使parentPane可见。当然childPane的可见状态也可以随时更改。是否可以创建动态Bindings.OR,以便我可以动态向其添加/删除子可见属性?如果是,那怎么办?如果没有,那么在这种情况下使用什么解决方案? 问题答案: 您可以

  • 问题内容: 自从我使用Java以来​​已经有5年了,那时,每当您想分配需要清理的对象(例如套接字,DB句柄)时,都必须记住添加一个块并在其中调用cleanup方法。那里。 相比之下,在C++(或确定对象生存期的其他语言,例如Perl)中,类实现程序将定义一个析构函数,该函数在该类的对象超出范围时执行清除。这种方法的优点是对象的用户不会忘记清理它- 即使抛出异常,析构函数也会被自动调用。这种方法用R

  • 在 3D 场景初始化后,我们可以通过 create() 方法来创建物体,例如,加载模型、添加标记、创建基本形体等。我们还可以通过 create() 方法来加载园区,例如,添加多个园区。通过 destroy() 方法,可以销毁物体,即在场景中删除物体。 创建物体的语法 下面的代码中,通过 create() 方法创建物体,并通过对象名称和属性,来添加所创建的物体属性。 var obj = app.cr

  • 问题内容: 如何在Python中使类或方法抽象? 我尝试像这样重新定义: 但是现在,如果我创建一个像这样继承的类: 那么我也无法实例化,因为它调用了其超类的方法。 有没有更好的方法来定义抽象类? 问题答案: 使用该模块创建抽象类。使用装饰器来声明方法摘要,并根据您的Python版本使用以下三种方式之一声明类摘要。 在Python 3.4及更高版本中,您可以从继承。在Python的早期版本中,您需要

  • 我想创建一个包含XFA数据的PDF,但我不想在查看PDF时看到XFA数据,但是,我希望可以通过以下代码访问它: 我怎么能这样呢? 谢谢