Activity 类中的静态字段是否保证比创建/销毁周期更长? [英] Are static fields in Activity classes guaranteed to outlive a create/destroy cycle?

查看:14
本文介绍了Activity 类中的静态字段是否保证比创建/销毁周期更长?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常遇到这样一个问题,即我必须在多次调用活动之间保留状态(即经历几个 onCreate()/onDelete() 循环).不幸的是,Android 对这样做的支持真的很差.

I frequently run into the problem that I have to preserve state between several invocations of an activity (i.e. going through several onCreate()/onDelete() cycles). Unfortunately, Android's support for doing that is really poor.

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

As an easy way to preserve state, I thought that since the class is only loaded once by the class loader, that it would be safe to store temporary data that's shared between several instances of an activity in a static Bundle field.

然而,偶尔,当实例 A 创建静态包并在其中存储数据,然后被销毁,并且实例 B 尝试从中读取时,静态字段突然为 NULL.

However, occasionally, when instance A creates the static bundle and stores data in it, then gets destroyed, and instance B tries to read from it, the static field is suddenly NULL.

这是否意味着在活动经历创建/销毁周期时类已被类加载器删除并重新加载?static 字段之前在引用对象时怎么会突然变成 NULL?

Doesn't that mean that the class had been removed and reloaded by the classloader while the activity was going through a create/destroy cycle? How else could a static field suddenly become NULL when it was referencing an object before?

推荐答案

这个答案的第一部分真的很旧 - 请参阅下面的正确方法

The first part of this answer is really old -- see below for the right way to do it

您可以使用 Application 对象来存储应用程序持久对象.这个 Android FAQ 也谈到了这个问题.

You can use the Application object to store application persistent objects. This Android FAQ talks about this problem as well.

像这样:

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();
    }
}

正确方式:

The right way:

当这个答案刚开始写的时候,Activity 生命周期的文档还没有现在那么好.阅读 Activity 文档中的 Saving Activity State 部分有助于我们了解 Android 的需求我们来保存状态.本质上,您的活动在两种情况下启动:(1)作为新活动和(2)因为配置更改或由于内存压力而被销毁后重新创建.当您的活动因为是新活动而启动时, saveInstanceState 为空.否则它不为空.如果它为空,那么您的活动应该从头开始初始化.片段与活动非常相似,我在我的 AnDevCon-14 幻灯片.您还可以查看我的 AnDevCon-14 演示文稿的示例代码以了解更多详细信息.

When this answer was first written, the documentation for the Activity lifecycle was not as good as it is now. Reading Saving Activity State section on the Activity document helps us understand how Android wants us to save state. Essentially, there are two circumstances under which your activity starts: (1) as a new activity and (2) because of a configuration change or when it's recreated after being destroyed due to memory pressure. When your activity starts because it's a new activity, then saveInstanceState is null. It's not null otherwise. If it's null, then your activity should initialize itself from scratch. Fragments are very similar to Activities, and I covered this concept in detail for my AnDevCon-14 slide deck. You can also take a look at the sample code for my AnDevCon-14 presentation for more details.

重新编写我之前的示例将类似于下面的代码.我确实稍微改变了语义——在第二个版本中,我假设字符串 thing 特定于特定 android task,在前面的例子中它是模棱两可的.如果您确实希望为多个 android 任务保留相同的数据,那么使用 Application 对象或另一个单例仍然是您最好的选择.

Reworking my previous example would look something like the code below. I do change the semantics a bit -- in this second version I assume the string thing is specific to the activity within a specific android task, in the previous example it's ambiguous. If you do want to keep the same data around for multiple android tasks, then using either the Application object or another singleton is still your best bet.

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);
    }
}

这篇关于Activity 类中的静态字段是否保证比创建/销毁周期更长?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆