SharedPreferences未更新 [英] SharedPreferences not being updated

查看:148
本文介绍了SharedPreferences未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having an odd issue in which the SharedPreferences are not being updated upon returning to an app. Here's the scenario:

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

I have two projects that use the same shared preferences. Project1 and Project2. They are separate but related apps. They are signed with the same key and use sharedUserId to share information.

Project1打开Project2.

Project1 opens Project2.

Project2检索SharedPreferences文件,并通过以下方法对其进行写入:

Project2 retrieves the SharedPreferences file and writes to it via this method:

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.

Once that is done, I return to Project1 by calling finish().

Project1然后像这样读取数据:

Project1 then reads the data like so:

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时,我需要对其进行更新.我觉得这里有些东西我想念,但是找不到.

The problem is the values are not updated in Project1. I can tell based off the logs at the end that the file isn't even generating mappings. However, I can verify that the xml is being updated. If I force stop the app then restart it, all the mappings are there in Project1. All the values are correct. However, I need them updated when the user leaves Project2. I feel like there's something I'm missing here but can not spot it.

关于这个主题,我唯一能找到的是:

The only things I have been able to find on the subject is:

SharedPreferences.初始提交后未更新编辑器

SharedPreferences值未更新

这些都无济于事,因为我已经这样做了.

These don't help as I'm already doing that.

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

I have WRITE_EXTERNAL_STORAGE set in both manifests. The fileName is the same (else I wouldn't be able to read the file when I reenter the app).

我应该注意,我确实尝试做editor.commit()而不是editor.apply(),因为我认为自己正面临比赛条件.问题仍然存在.我在想,出于某种原因,即使我每次都在懒惰地加载它,也正在使用Project1中对SharedPreference的旧引用,而不是新的引用.

I should note that I did try to do editor.commit() instead of editor.apply() as I thought I was facing a race condition. The problem still persisted. I'm thinking that for some reason, the old reference to the SharedPreference in Project1 is being used instead of a new one even though I'm lazy-loading it each time.

好,进一步测试以查看发生了什么ID.我决定尝试相反的方向.

Ok, to further test to see what id going on. I decided to try the opposite direction.

在Project1中,我这样做:

In Project1 I do:

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

在Project2中,我这样做:

In Project2 I do:

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

然后我像这样在两个之间来回移动:Project1->Project2->Project1->Project2->Project1->Project2这是logcat的结果:

I then go back and forth between the two like so: Project1->Project2->Project1->Project2->Project1->Project2 and here is the logcat result:

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

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

In other words, it's reading and writing to the same file. However, it's keeping the mapping that it had when it was first opened it in the project. Even though I close the project, the mapping remains until the application is force stopped.

推荐答案

最终答案:

替换

getSharedPreferences(fileName, Context.MODE_PRIVATE);

使用

getSharedPreferences(fileName, Context.MODE_MULTI_PROCESS);

根据文档:

Context.MODE_MULTI_PROCESS

Context.MODE_MULTI_PROCESS

SharedPreferences加载标志:设置后,磁盘上的文件将为 即使共享首选项实例为 已在此过程中加载.有时在 应用程序具有多个进程的情况下,所有进程都写入 相同的SharedPreferences文件.通常有更好的形式 进程之间的通信.

SharedPreferences loading flag: when set, the file on disk will be checked for modification even if the shared preferences instance is already loaded in this process. This behavior is sometimes desired in cases where the application has multiple processes, all writing to the same SharedPreferences file. Generally there are better forms of communication between processes, though.

这是之前和之后的遗留(但未记录)行为 Gingerbread(Android 2.3),并且在定位时隐含此标志 这样的发行.对于面向SDK版本大于的应用程序 Android 2.3(姜饼),如果需要,必须显式设置此标志.

This was the legacy (but undocumented) behavior in and before Gingerbread (Android 2.3) and this flag is implied when targeting such releases. For applications targeting SDK versions greater than Android 2.3(Gingerbread), this flag must be explicitly set if desired.

我知道这是一个简单的疏忽.

I knew there was a simple oversight in this.

这篇关于SharedPreferences未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆