Android共享偏好设置不保存

47
我创建了一个Android实时壁纸,并尝试让用户从他们的手机中选择一张图片作为背景图像,但是当我启动活动来开始选择图片时,我的共享首选项似乎不能正确保存。
以下是我在用户按下首选项按钮时启动的活动的onCreate方法和获取设备上图片路径的onActivityResult方法(所有这些似乎都有效)。我提交首选项后的println没有输出任何内容。
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
    photoPickerIntent.setType("image/*");
    startActivityForResult(photoPickerIntent, SELECT_PICTURE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);

            preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
            preferences.edit().putString(SETTINGS_BACKGROUND_IMAGE, "okok");
            preferences.edit().commit();

            System.out.println("Image" + preferences.getString(SETTINGS_BACKGROUND_IMAGE, ""));
        }
    }

    finish();
}
5个回答

98

文档中了解到:

创建一个新的编辑器(Editor)以修改偏好设置(preferences),通过这个编辑器(Editor)可以对偏好设置中的数据进行修改,并原子性地将更改提交回SharedPreferences对象。

由于这是一个新的编辑器(Editor)实例,因此您的代码应该更像这样:

preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.apply();

27
我是唯一一个看不出这段代码和原始代码逻辑区别的人吗? - josephus
48
当您调用preferences.edit()时,您会获得一个Editor实例。jOE在该实例上放置了一个字符串,但在此之后,该实例不再使用(因此丢失,可能被垃圾回收)。然后,jOE再次调用preferences.edit(),获得另一个Editor实例,其中包含最初的设置,他只是将其保存在原地。这基本上只保存了最初的设置(没有更新共享首选项)。 - zrgiu
1
zrgui,非常感谢您的帮助!您的建议完美地解决了问题! - jOE
2
谢谢,你救了我的一天。问题中描述的共享首选项的行为对我来说真的很令人困惑。 - gmuhammad
能否在SharedPreferences中传递除字符串以外的对象? - amit pandya
显示剩余2条评论

16

尝试使用另一种方式初始化SharedPreferences变量:

SharedPreferences sf = PreferenceManager.getDefaultSharedPreferences(this);

你还可以使用 sf.edit().putString(string, value).commit(); 进行链式写入。


1
我不想再把它链接起来了。 - Sagar Hatekar

3

根据@zrgiu的帖子,对我而言只需在使用编辑器之前添加editor.clear();即可使其正常工作...因此最终代码将类似于:

preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.commit();

;)

2
这对我有用,但你能解释一下为什么会发生这种情况吗? - Ravi Mishra
对我来说工作正常。 - mani kandan

0
在我的情况下,我必须在提交之前添加 editor.apply(); 以使其正常工作。
这是我的代码:
preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.apply();//I added this line and started to work...
editor.commit();

12
应用"apply"是异步保存数据,而"commit"是立即保存数据。你不应同时使用它们!!! - XcodeNOOB

0
请记住,您需要相同的活动来保存和检索数据。您不能使用像这样的方法:
public String readValue(Activity activity, String key) {
    SharedPreferences sp = activity.getPreferences(Context.Mode_PRIVATE);
   //...
}

如果你需要从同一个 Activity 中获取相同的数据,你需要使用与你保存数据所在的 Activity 完全相同的 Activity 来调用此方法。


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