将 Bundle 保存到 SharedPreferences [英] Save Bundle to SharedPreferences

查看:22
本文介绍了将 Bundle 保存到 SharedPreferences的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已竭尽全力将我的 Android 游戏的所有数据都放入 savedInstanceState Bundle.总共有很多数据,包括许多 Parcelable 对象.这样可以确保在应用暂停或方向更改时,重新创建的 Activity 不会丢失任何数据.

I've gone to great lengths to make all of the data for my Android game fit into a savedInstanceState Bundle. There's a lot of data altogether, including many Parcelable objects. This ensures that when the app is paused or the orientation changes, no data gets lost by the Activity being recreated.

但是,我最近发现 savedInstanceState 包显然不适合长期存储.因此,我正在寻找一种可以调整现有保存方法以作为长期解决方案的方法,以便始终可以恢复游戏状态.

However, I have just recently discovered that a savedInstanceState bundle is apparently NOT appropriate for long-term storage. So I'm looking for a way that I can adapt my existing save method to work as a long-term solution, so that the game state can always be restored.

到目前为止,我听说过两种解决方案:

I have heard of 2 solutions so far:

1) 使用 savedInstanceState 包进行方向更改,但也包含 SharedPrefs 以在应用需要完全关闭时使用.

这似乎会适得其反,因为它使用两种完全不同的方法来完成基本相同的事情.此外,由于我的 savedInstanceState Bundle 使用 Parcelable 对象,我必须为这些对象中的每一个提供另一种方法,以使它们能够写入 SharedPrefs.本质上是大量重复且难以管理的代码.

This seems incredibly counter-productive, as it uses 2 different completely methods to do basically the same thing. Also, since my savedInstanceState Bundle uses Parcelable objects, I would have to give each of those objects another method to enable them to be written to SharedPrefs. Essentially LOTS of duplicated and difficult-to-manage code.

2) 序列化 savedInstanceState Bundle 并将其直接写入文件.

我对此持开放态度,但我实际上不知道如何去做.但是,我仍然希望有更好的解决方案,因为我听说 Android 中的序列化是可笑/无法使用的缓慢".

I am open to this, but I don't actually know how to go about doing it. However, I'm still holding onto the hope that there may be a better solution, as I've heard that serialization in Android is "comically / unusably slow".

如果有人能为我提供解决方案,我将不胜感激.

I would be extremely grateful if someone could provide me with a solution to this.

推荐答案

我现在想出了自己的解决方案来解决这个问题,这是一种将 Bundles 保存到 SharedPreferences 的半自动方法.我说半自动是因为,虽然保存 Bundle 只需要一种方法,但再次检索数据并将其转回 Bundle 需要一些工作.

I have now come up with my own solution to this problem, which is a semi-automatic means of saving Bundles to SharedPreferences. I say semi-automatic because, although saving the Bundle requires only one method, retrieving the data again and turning it back into a Bundle takes some work.

这是保存Bundle的代码:

Here is the code to save the Bundle:

SharedPreferences save = getSharedPreferences(SAVE, MODE_PRIVATE);
Editor ed = save.edit();
saveBundle(ed, "", gameState);

/**
 * Manually save a Bundle object to SharedPreferences.
 * @param ed
 * @param header
 * @param gameState
 */
private void saveBundle(Editor ed, String header, Bundle gameState) {
    Set<String> keySet = gameState.keySet();
    Iterator<String> it = keySet.iterator();

    while (it.hasNext()){
        key = it.next();
        o = gameState.get(key);
        if (o == null){
            ed.remove(header + key);
        } else if (o instanceof Integer){
            ed.putInt(header + key, (Integer) o);
        } else if (o instanceof Long){
            ed.putLong(header + key, (Long) o);
        } else if (o instanceof Boolean){
            ed.putBoolean(header + key, (Boolean) o);
        } else if (o instanceof CharSequence){
            ed.putString(header + key, ((CharSequence) o).toString());
        } else if (o instanceof Bundle){
            saveBundle(header + key, ((Bundle) o));
        }
    }

    ed.commit();
}

请注意,我只为我需要的类型编写了案例,但如果您的 Bundles 还包含其他类型,这应该很容易适应.

Note that I have only written cases for the types I needed, but this should be easily adaptable if you have Bundles that also include other types.

此方法将递归保存存储在给定 Bundle 中的其他 Bundle 对象.但是,它不适用于 Parcelable 对象,因此我必须更改我的 Parcelable 对象以使它们将自己存储到 Bundle 中.由于 Parcels 和 Bundles 非常相似,这并不难.不幸的是,我认为捆绑包也可能比包裹稍慢.

This method will recursively save other Bundle objects stored inside the given Bundle. However, it will not work for Parcelable objects, so I had to alter my Parcelable objects to make them store themselves into a Bundle instead. Since Parcels and Bundles are pretty similar, this wasn't too hard. I think Bundles may also be slightly slower than Parcels, unfortunately.

然后,我在所有以前的 Parcelable 对象中编写了构造函数,以使它们能够从存储的 SharedPreferences 数据中重新捆绑自己.重建所需数据的密钥很容易.假设您有以下数据结构:

I then wrote constructors in all of my previously-Parcelable objects to enable them to re-Bundle themselves from the data stored SharedPreferences. It's easy enough to reconstruct the keys to the data you need. Say you have the following data structure:

Bundle b {
    KEY_X -> int x;
    KEY_Y -> Bundle y {
                 KEY_Z -> int z;
             }
}

这些将按如下方式保存到 SharedPreferences:

These will be saved to SharedPreferences as follows:

KEY_X -> x
KEY_YKEY_Z -> z

它可能不是世界上最漂亮的方法,但它很有效,而且它花费的代码比其他方法少得多,因为现在我的 onSaveInstanceState 方法和我的 onPause 方法使用相同的技术.

It may not be the prettiest method in the world, but it works, and it cost me much less code than the alternative, since now my onSaveInstanceState method and my onPause methods use the same technique.

这篇关于将 Bundle 保存到 SharedPreferences的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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