English 中文(简体)
Android 共享首选项未保存
原标题:Android SharedPreferences not saving

我曾经使用过很多次共享优惠,但出于某种原因,我测试的一个新应用程序并没有保存更改。这里是重要代码的片断:

SharedPreferences sp = getSharedPreferences(getString(R.string.key_preferences), MODE_PRIVATE);
Set<String> widgets = sp.getStringSet(getString(R.string.key_widgets), (new HashSet<String>()));
widgets.add(name + " " + Integer.toString(appWidgetId) + " " + address);
sp.edit().putStringSet(getString(R.string.key_widgets), widgets).commit();

我曾经用日志来检查部件是否添加到集中, 但更新后的集从未保存。 如果我将最后一行更改为...

sp.edit().putStringSet(getString(R.string.key_widgets), widgets).putString("testkey", "testvalue").commit();

一切都会好起来的 我错过了什么?

* 过时:

我发现这也有效:

SharedPreferences sp = getSharedPreferences(getString(R.string.key_preferences), MODE_PRIVATE);
Set<String> widgets = sp.getStringSet(getString(R.string.key_widgets), (new HashSet<String>()));
Set<String> newWidgets = new HashSet<String>();
for (String widget : widgets) newWidgets.add(widget);
newWidgets.add(name + " " + Integer.toString(appWidgetId) + " " + address);
sp.edit().putStringSet(getString(R.string.key_widgets), newWidgets).commit();

也许我在文档中遗漏了 需要为编辑 创建一个新对象来保存预设文件的内容。

* 日期:

如果我创建一个编辑器对象,这没有什么区别:

SharePreferences.Editor spe = sp.edit();
spe.putStringSet(getString(R.string.key_widgets), widgets)
spe.commit();
最佳回答

我们只需要更仔细地阅读文件

根据getStringSet

请注意, 您不能修改此调用返回的设置实例。 如果您这样做, 存储数据的一致性得不到保证, 您也根本无法修改该实例 。

事实上,在“强度共享”索引中应该注意的是,不要发送“强度”StringSet(强度)/强度(强度)来发送此后可能修改的集。在修改前,从“强度”getStringSet(强度)返回的集复制件,在发送到“StringSet”(StringSet)之前,要复制你的集。

SharedPreferences myPrefs = getSharedPreferences(myPrefName, MODE_PRIVATE);
HashSet<String> mySet = new HashSet<string>(myPrefs.getStringSet(mySetKey, new HashSet<string()));
....
SharedPreferences.Edit或 myEdit或 = myPrefs.edit();

然后一个

myEdit或.putStringSet(mySetKey, new HashSet<String>(mySet));

myEdit或.putStringSet(mySetKey, (Set<String>) mySet.clone());
问题回答

我想改进> Chike 回答一点。

Cause

“强势”义务() rel=“noreferr” > 执行 (自v4.0.1以来未改变),它承诺首先记忆,然后等待磁盘写完:

public boolean commit() {
    MemoryCommitResult mcr = commitToMemory();
    SharedPreferencesImpl.this.enqueueDiskWrite(
        mcr, null /* sync write on this thread okay */);
    try {
        mcr.writtenToDiskLatch.await();
    } catch (InterruptedException e) {
        return false;
    }
    notifyListeners(mcr);
    return mcr.writeToDiskResult;
}

点是,如果我们从“强”getStringSet ()

// Returns true if any changes were made
private MemoryCommitResult commitToMemory() {
    MemoryCommitResult mcr = new MemoryCommitResult();
    ...
            for (Map.Entry<String, Object> e : mModified.entrySet()) {
                String k = e.getKey();
                Object v = e.getValue();
                ...
                    if (mMap.containsKey(k)) {
                        Object existingValue = mMap.get(k);
                        if (existingValue != null && existingValue.equals(v)) {
                            continue;
                        }
                    }
                    mMap.put(k, v);
                }

                mcr.changesMade = true;
                ...
            }
            ...
        }
    }
    return mcr;
}

由于没有更改, < strong > writeToFile () 高兴地跳过磁盘写入并设定成功标记 :

private void writeToFile(MemoryCommitResult mcr) {
    // Rename the current file so it may be used as a backup during the next read
    if (mFile.exists()) {
        if (!mcr.changesMade) {
            // If the file already exists, but no changes were
            // made to the underlying map, it s wasteful to
            // re-write the file.  Return as if we wrote it
            // out.
            mcr.setDiskWriteResult(true);
            return;
        }
        ...
    }
    ...
}

Solution

请参见“https://stackoverflow.com/a/20830010/1825443>> Chike s 回答,在将字符串保存到同一个共享首选项之前,先复制该字符串。

您需要保存编辑器对象, 然后调用执行 () (在 Android 2. 3之前) 或应用 (在 Android 2. 3及以上) 。

SharedPreferences.Editor editor = sp.edit();
editor.put...
editor.commit();

我遇到的问题和你描述的一样

我的布林和字符串偏好没有问题, 但是当我试图存储一个字符串组时, 问题就开始了。

当我在字符串设置中添加第一个元素并存储它时,它就起作用了。但是,当我试图添加第二个元素时,它被添加到记忆中(我可以刷新显示该首选中存储的所有元素的视图 ) 。 如果我强制关闭应用程序并重新启动它, 共享的首选仅添加第一个元素 。

我调试了我的代码, 并看到我存储我的字符串的HashSet 当我添加一个新字符串时是正常的, 但更改没有写入持续存储中 。

共同优惠使用以下结构 :

< 加强>1. 创建对象

SharedPreferences myPrefs = context.getSharedPreferences(PREF_NAME, MODE_WORLD_READABLE);

<强 > 2. 要在共享首选项中保存值

为共享首选项创建一个编辑器 :

SharedPreferences.Editor prefsEditor = myPrefs .edit();

然后将值放入编辑器 :

prefsEditor.putString("KEY", VALUE);

现在承诺更改以保存共享首选项 :

prefsEditor.commit();

我把下面的代码 在Create方法上, 所以它会重新设置 每次我重新启动应用程序。

    preferences.edit().putInt(...).apply();

使用此处所说的方法 : < a href="https://stackoverflow.com/a/28789934/11266070" >https://stackoverflow.com/a/28789934/11266070

    SharedPreferences sharedPrefs = getSharedPreferences("sp_name", MODE_PRIVATE);
    SharedPreferences.Editor ed;
    if(!sharedPrefs.contains("initialized")){
        ed = sharedPrefs.edit();

        //Indicate that the default shared prefs have been set
        ed.putBoolean("initialized", true);

        //Set some default shared pref
        ed.putString("myDefString", "wowsaBowsa");

        ed.commit();
    }  

希望这能提醒某人...





相关问题
Android - ListView fling gesture triggers context menu

I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

Android intent filter for a particular file extension?

I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...

Android & Web: What is the equivalent style for the web?

I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...

TiledLayer equivalent in Android [duplicate]

To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?

Using Repo with Msysgit

When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error: /c/Users/Andrew Rabon/bin/repo: line ...

Android "single top" launch mode and onNewIntent method

I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...

From Web Development to Android Development

I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ? Also what new languages would I ...

热门标签