【问题标题】:How to merge 2 SharedPreferences into one?如何将 2 个 SharedPreferences 合并为一个?
【发布时间】:2016-08-29 14:58:29
【问题描述】:

假设我有 2 个 sharedPreferences 文件,一个是通过“PreferenceManager.getDefaultSharedPreferences(...);”创建的,一个是通过 getSharedPreferences(someString, Context.MODE_PRIVATE) 创建的",而且我知道两者的键都是唯一的。

如何将所有键和值从一个文件移动到另一个文件?

有没有简单的方法来移动它们?

我正在考虑使用类似于this answer 的代码,但我不需要考虑那里每个值的类型吗?

编辑:

这是一种方法,但有点不安全,因为将来可能会将新类型添加到 SharedPreferences 中,这意味着它将不受支持:

        final Editor edit = targetSharedPreferences.edit();
        final Map<String, ?> srcSharedPreferenceAll = srcSharedPreference.getAll();
        for (final Entry<String, ?> entry : srcSharedPreferenceAll.entrySet()) {
            if (entry.getValue() instanceof Integer)
                edit.putInt(entry.getKey(), (Integer) entry.getValue());
            else if (entry.getValue() instanceof Boolean)
                edit.putBoolean(entry.getKey(), (Boolean) entry.getValue());
            else if (entry.getValue() instanceof Long)
                edit.putLong(entry.getKey(), (Long) entry.getValue());
            else if (entry.getValue() instanceof String)
                edit.putString(entry.getKey(), (String) entry.getValue());
            else if (entry.getValue() instanceof Float)
                edit.putFloat(entry.getKey(), (Float) entry.getValue());
            else if (entry.getValue() instanceof Set<?>)
                edit.putStringSet(entry.getKey(), (Set<String>) entry.getValue());
        }
        edit.apply();
        srcSharedPreference.edit().clear().apply();

我已经成功地将 xml 标记从一个 SharedPreference 文件复制到另一个文件,但由于某种原因,它只会在下一个会话中被 SharedPreference 对象注意到,而不是当前会话(可能它已被缓存)。代码如下:

    private static final String DST_XML_FILE = "dst";

    // creating the data, for reading&writing later:
    final SharedPreferences srcSharedPreference = getSharedPreferences(String , Context.MODE_PRIVATE);
    srcSharedPreference.edit().clear().putInt("someInt", 12).putString("someString", "hi").putBoolean("someBoolean", true).apply();
    final SharedPreferences targetSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    targetSharedPreferences.edit().clear().putInt("someInt2", 23).putString("someString2", "hi there").putBoolean("someBoolean2", false).apply(); 

    //checking content before
    Log.d("AppLog", "before");
    final Map<String, ?> src = srcSharedPreference.getAll();
    Log.d("AppLog", "src:" + src.size());
    final Map<String, ?> targetSharedPreferencesAll = targetSharedPreferences.getAll();
    Log.d("AppLog", "target:" + targetSharedPreferencesAll.size());

    // the moving of the XML tags:
    final PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
    File dstFile = new File(packageInfo.applicationInfo.dataDir, "shared_prefs/" + (VERSION.SDK_INT >= VERSION_CODES.N ? PreferenceManager.getDefaultSharedPreferencesName(this) : getPackageName() + "_preferences") + ".xml");
    File srcFile = new File(packageInfo.applicationInfo.dataDir, "shared_prefs/" + SRC_XML_FILE + ".xml");

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    Node srcNode = docFactory.newDocumentBuilder().parse(srcFile).getFirstChild();
    Node dstNode = docFactory.newDocumentBuilder().parse(dstFile).getFirstChild();
    final NodeList childNodes = srcNode.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); ++i) {
        final Node item = childNodes.item(i);
        Node importedNode = dstNode.getOwnerDocument().importNode(item, true);
        srcNode.removeChild(item);
        dstNode.appendChild(importedNode);
    }
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(dstNode);
    StreamResult result = new StreamResult(dstFile);
    transformer.transform(source, result);

    //checking content after
    Log.d("AppLog", "after");
    final Map<String, ?> src = srcSharedPreference.getAll();
    Log.d("AppLog", "src:" + src.size());
    final Map<String, ?> targetSharedPreferencesAll = targetSharedPreferences.getAll();
    Log.d("AppLog", "target:" + targetSharedPreferencesAll.size());

【问题讨论】:

    标签: android sharedpreferences


    【解决方案1】:
    Map<String,?> keys = prefs.getAll();
    for(Map.Entry<String,?> entry : keys.entrySet()){
            Object o = keys.get(entry);
            if (o instanceof Boolean)
            {
                pref2.putBoolean(o);
            }
            if (o instanceof String)
            {
                pref2.putString(o);
            }
            ...
        }
    }  
    

    【讨论】:

    • 能否请您显示“放入其他首选项”的代码?
    • 所以我需要检查每个对象的类型?有更好的选择吗?也许将其全部作为 XML 标记处理?
    • 您通过SharedPreferences.Editor 输入值。
    • @EugenPechanec 是的,但是有没有更好的方法,我不需要检查地图中每个值的类型?当前的实现并不安全,因为如果有新类型,它将不支持它们。
    • @androiddeveloper 没有更快的方法。不会有更多类型。如果有任何机会,您将相应地更新代码。 (您最后一次存储设置为共享首选项的字符串是什么时候?只需支持原语并完成它。)
    猜你喜欢
    • 2018-04-26
    • 2017-12-11
    • 2021-09-22
    • 2022-08-17
    • 2010-10-07
    • 2014-02-07
    • 2018-10-30
    • 2021-04-05
    • 2016-10-06
    相关资源
    最近更新 更多