SharedPreferences未更新

时间:2012-09-27 22:25:23

标签: android sharedpreferences

我遇到一个奇怪的问题,即在返回应用程序时没有更新SharedPreferences。这是场景:

我有两个使用相同共享首选项的项目。 Project1和Project2。它们是独立但相关的应用程序。它们使用相同的密钥签名,并使用sharedUserId来共享信息。

Project1打开Project2。

Project2检索SharedPreferences文件并通过以下方法写入:

Context prefsContext = c.createPackageContext(packageNameOfProject1, Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences prefs = prefsContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
SharedPreferences.editor editor = prefs.edit();
editor.putBool("bool1", value1);
editor.putBool("bool2", value2);
...
editor.putBool("boolN", valueN);
editor.apply();

完成后,我通过调用finish()返回Project1。

Project1然后读取数据:

SharedPreferences prefs = getSharedPreferences(getPreferencesFileName(), Context.MODE_PRIVATE);
Boolean value1 = prefs.getBoolean(fileName, false);
Boolean value2 = prefs.getBoolean(fileName, false);
...
Boolean valueN = prefs.getBoolean(fileName, false);
Map<String, ?> mappings = prefs.getAll();
Set<String> keys = mappings.keySet();
for(String key : keys) {
  log.d(TAG, "_____");
  log.d(TAG, "Key = " + key);
  log.d(TAG, "Value = " + mappings.get(key));
}

问题是Project1中的值未更新。我可以根据最后的日志告诉文件甚至不生成映射。但是,我可以验证xml是否正在更新。如果我强制停止应用程序然后重新启动它,Project1中的所有映射都在那里。所有的值都是正确的。但是,当用户离开Project2时,我需要更新它们。我觉得这里有一些我不知道但却找不到的东西。

我在这个问题上唯一能找到的是:

SharedPreferences.Editor not being updated after initial commit

SharedPreferences value is not updated

这些没有用,因为我已经这样做了。

我在两个清单中都设置了WRITE_EXTERNAL_STORAGE。 fileName是相同的(否则当我重新进入应用程序时我将无法读取该文件)。

编辑:

我应该注意到我确实尝试editor.commit()而不是editor.apply()因为我认为我正面临着竞争条件。问题仍然存在。我想由于某种原因,使用Project1中的SharedPreference的旧引用而不是新的引用,即使我每次都懒得加载它。

EDIT2:

好的,进一步测试看看id是怎么回事。我决定尝试相反的方向。

在Project1中我做:

Float testFloat (float) Math.random();
Log.d("TEST_FLOAT", "Project1: TEST_FLOAT = " + testFloat);
prefs.edit().putFloat("TEST_FLOAT", testFloat).commit();

在Project2中我做:

Log.d("TEST_FLOAT", "Project2: TEST_FLOAT = " + prefs.getFloat("TEST_FLOAT", 0.0f));

然后我在两者之间来回走动:Project1->Project2->Project1->Project2->Project1->Project2这里是logcat的结果:

Project1: TEST_FLOAT = 0.30341884
Project2: TEST_FLOAT = 0.30341884
Project1: TEST_FLOAT = 0.89398974
Project2: TEST_FLOAT = 0.30341884
Project1: TEST_FLOAT = 0.81929415
Project2: TEST_FLOAT = 0.30341884

换句话说,它正在读取和写入同一个文件。但是,它保留了在项目中首次打开它时所具有的映射。即使我关闭了项目,映射仍然存在,直到应用程序被强制停止。

3 个答案:

答案 0 :(得分:19)

最终答案:

替换

getSharedPreferences(fileName, Context.MODE_PRIVATE);

getSharedPreferences(fileName, Context.MODE_MULTI_PROCESS);

根据文件:

  

Context.MODE_MULTI_PROCESS

     

SharedPreferences loading flag:设置后,磁盘上的文件将是   即使共享首选项实例是,也检查了修改   已加载此过程。有时需要这种行为   应用程序有多个进程的情况,都写入   相同的SharedPreferences文件。一般来说有更好的形式   但是,流程之间的沟通。

     

这是之前和之前的遗留(但未记录)行为   姜饼(Android 2.3)和此标志在定位时隐含   这样的发布。对于针对大于的SDK版本的应用程序   Android 2.3(Gingerbread),如果需要,必须明确设置此标志。

我知道这有一个简单的疏忽。

答案 1 :(得分:1)

尝试拨打editor.commit();而不是editor.apply();。通常他们也应该这样做,但我注意到有时会出现一些奇怪的行为。

答案 2 :(得分:1)

在SharedPreferences文档中,方法“apply()”异步(延迟)写入文件,方法“commit()”将信息同步(立即)写入文件。

同样从文档中,他们说您在使用上述任何方法时都不需要担心活动生命周期,因为它们确保在状态更改之前完成“apply()”写入,如果它们是在同一系统进程中运行。

但是,当您使用两个不同的项目时,它们运行在两个不同的进程中,您无法确定项目2上的“apply()”将在“onResume()”在项目1上启动之前结束。

我建议你尝试“commit()”而不是“apply()”来强制同步写入。如果这不能解决问题,您可以在读取项目1中的首选项之前添加几秒钟的延迟,只是为了检查问题是否与此延迟写入有关。

- 编辑 -

要调试此问题,请执行以下操作:

1-In Eclipse选择/添加视图“文件资源管理器”并导航到目录:

/ data / data / [您的包名] / shared_prefs

您的包名应该类似于“com.myproject.shared”

2 - 选择包含已保存首选项的文件,然后按“下载到PC”按钮。

3 - 检查文件内容是否符合您的期望。

祝你好运。