SharedPreferences不持久化

11

我在 Android 中使用了 SharedPreferences。在同一次会话中,一切都很顺利。

然而,一旦我重新启动应用程序,之前会话中设置的所有首选项都丢失了。

我需要指定什么来让 SharedPreferences 在运行时保留下来吗?

我是通过调用以下代码创建首选项的:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);

然后我通过例如下面的方式设置属性:

preferences.edit().putString(key, value);

我通过以下方式获取它

preferences.getString(key, defaultValue);

谢谢,Victor


2
你写了editor.commit()吗? - Richa
3
如果你的Set<String>在应用程序会话之间没有保存,那是因为存在一个错误。使用这个解决方法:https://dev59.com/9WQm5IYBdhLWcg3wnAGR#26315757。 - Sakiboy
非常感谢你,Sakiboy。我浪费了将近4个小时来弄清楚为什么在调用提交后,在同一上下文中验证更改,但然后切换到另一个上下文时,我更新的值会恢复到旧值。Android请记录这些内容并尽职尽责,这样我就可以做我的工作了。因为某种原因,Android/Google的文档很差...天哪!我在CPU上浪费了4个小时。 - JamisonMan111
8个回答

30

SharedPreferences是持久化存在的,即使应用重启或者重新加载也可以读取到。我认为问题在于你没有提交这些偏好设置,使用以下代码将值存储到偏好设置:

Preferences.Editor edit=preferences.edit();
edit.putString(key, value);
edit.commit();

3
apply()commit()更好,因为它允许写入在后台进行。 - levengli

24

你很可能没有提交你的更改。设置属性如下:

SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.commit();

如果没有提交,你就像在风中放屁一样。


3
升级了,速度惊人 :D - droidchef

4
这对我有效,请尝试一下:
private SharedPreferences mShared;
private Editor mEdit;
mShared = PreferenceManager.getDefaultSharedPreferences(this);

mEdit = mShared.edit();
mEdit.putString(key, value);
mEdit.commit();

2

获取偏好设置中的值

SharedPreferences pref1 = getSharedPreferences(PREFS_NAME, 0);
boolean silent = pref1.getString("silentMode", "...");

为了保存值,请使用onCreate或onPause方法。

SharedPreferences pref2 = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = pref2.edit();
editor.putString("silentMode", "...");

那对我来说很好,并且健康。

1
这是适用于我的代码。

package com.example.persistence;

import android.os.Bundle;
import android.widget.EditText;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;


public class MainActivity extends Activity {

public static final String NOTE_PREFS="note";
SharedPreferences msgSettings;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     msgSettings = getSharedPreferences(NOTE_PREFS,0);

      EditText et= (EditText)findViewById(R.id.editText1);
      if (msgSettings.contains(NOTE_PREFS)) {
            et.setText(msgSettings.getString(
                    NOTE_PREFS, "my note")); 

    }

}
@Override
protected void onPause() {
      EditText et= (EditText)findViewById(R.id.editText1);
      String b = et.getText().toString();
      Editor editor = msgSettings.edit();
      editor.putString(NOTE_PREFS,b);
        editor.commit();
    super.onPause();
}
@Override
protected void onDestroy() {
     EditText et= (EditText)findViewById(R.id.editText1);
      String b = et.getText().toString();
      Editor editor = msgSettings.edit();
      editor.putString(NOTE_PREFS,b);
        editor.commit();
    super.onDestroy();
}

    }

1
如果您正在开发API级别?及以上的应用程序,则在以编程方式修改首选项时应使用editor.apply()而不是editor.commit()editor.commit()已被弃用,editor.apply()将在后台处理实际持久性,而editor.commit()则不会这样做。
请注意,editor.apply()如果失败,则会静默失败。

这是错误的:commit()根本没有被弃用。API 22中唯一的提示是:如果您不关心返回值并且正在从应用程序的主线程使用它,请考虑改用{@link #apply}。 - Stéphane

0

除非您提交偏好设置,否则它们将不会被保存,即:

// DON'T DO THIS... See Next Example
preferences.edit().putString(key, value);
preferences.edit().commit();

编辑:上述代码存在一个细微的错误(来自评论);您需要保留对编辑器对象的引用,否则提交值的上述示例将创建一个新实例。应该是:

Preferences.Editor edit = preferences.edit();
edit.putString(key, value);
edit.commit();

参考自Android文档

请注意,您必须调用commit()才能使您在编辑器中进行的任何更改实际上显示在SharedPreferences中。


这段代码是错误的,因为您正在提交到一个不同的编辑器实例,而不是您放置字符串的那个实例。 - ffleandro
@ffleandro - 如果这段代码是错误的,那么其他所有回答都是错误的。 - Metro Smurf
2
不,我看到了很多正确的答案。你的答案问题在于当你调用preferences.edit()时,你创建了一个SharedPreferences.Editor对象。当你commit时,你提交的是一个不同的实例而不是你调用putString的那个实例,因此它不会持久化。我建议你再次阅读你发布的文档 - ffleandro

0

很多时间已经过去,但你可以使用

.apply() 

替代

.commit()

那样会更好。commit试图立即写入,但apply是异步的。以下是来自Google文档的解释:

与commit不同,它同步将其首选项写入持久存储,apply将其更改立即提交到内存中的SharedPreferences,但开始异步提交到磁盘,并且您不会收到任何失败通知。如果此SharedPreferences上的另一个编辑器执行常规提交,而仍有一个apply未完成,则提交将阻塞,直到所有异步提交以及提交本身都已完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接