Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

android - SharedPreferences not being updated

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

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 opens Project2.

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();

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

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));
}

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.Editor not being updated after initial commit

SharedPreferences value is not updated

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

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).

EDIT:

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.

EDIT2:

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

In Project1 I do:

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

In Project2 I do:

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

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Final answer:

Replace

getSharedPreferences(fileName, Context.MODE_PRIVATE);

with

getSharedPreferences(fileName, Context.MODE_MULTI_PROCESS);

As per document:

Context.MODE_MULTI_PROCESS

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...