[android-developers] Re: why does SharedPreferences framework allow you to insert a preference with a null key - given it can't reload the preferences afterwards?
On Wednesday, October 30, 2013 7:44:17 PM UTC+2, Nobu Games wrote:
I quickly peeked into the source code and well, this is the way how it is programmed. When an exception occurs while the preferences data file gets read, SharedPreferences sets internally an empty map so you start from scratch. I even dug a bit deeper. The XML serializer just ignores NULL keys and creates XML output that cannot be properly read anymore through the map deserialization method which seems to expect an existing key value.
My question is really why was it allowed to insert a null key in the first place - why not throw a NPE immediately (and say so in the docs) ?
If you read my links (point 3 here) you will see that null keys are perfectly valid : - they fail only on loading the prefs - taking down everything with them
They should either fix deserialization or prohibit null keys
If you read my links (point 3 here) you will see that null keys are perfectly valid : - they fail only on loading the prefs - taking down everything with them
They should either fix deserialization or prohibit null keys
As for why it has been programmed like that... I think the reasoning may be that preferences are not deemed to be of so much importance that it should make the app crash in case of failure. This error state is silently discarded and you start over with the defaults. I think that's a reasonable approach since any app should be able to start over with empty preferences.
Not at all - Shared Preferences is a documented persistence mechanism - it is as reasonable as deleting a database without even saying so
In this particular case you may have discovered a tiny bug you may want to report. But to be honest, using null keys is a pretty unusual thing to do.
Not so (either by mistake or not).
See the discussions in the SO. Some more I suspect they may have to do with null keys :
sharedpreferences - Android - Shared Preferences are lost sometimes - Stack Overflow
http://stackoverflow.com/questions/7943573/android-shared-preferences-are-lost-sometimes
android - Shared Preferences get lost after shutting down device or killing the app - Stack Overflow
http://stackoverflow.com/questions/9803838/shared-preferences-get-lost-after-shutting-down-device-or-killing-the-app#comment12495021_9803838
sharedpreferences - Android - Shared Preferences are lost sometimes - Stack Overflow
http://stackoverflow.com/questions/7943573/android-shared-preferences-are-lost-sometimes
android - Shared Preferences get lost after shutting down device or killing the app - Stack Overflow
http://stackoverflow.com/questions/9803838/shared-preferences-get-lost-after-shutting-down-device-or-killing-the-app#comment12495021_9803838
On Wednesday, October 30, 2013 5:48:12 AM UTC-5, Palmer Eldritch wrote:The preferences are apparently cleared when one tries to load them when there is a null key which is bad ! Reproducer :
public class XmlExceptionTest extends AndroidTestCase {
/** Run it twice - on the second run the exception is thrown */
public void testXmlException() {
Context ctx = getContext();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(ctx); // exception thrown here (line 18)
// and apparently it clears the prefs as the condition below is false
if (prefs.contains("run_once")) { // false
Log.w("XmlExceptionTest",
"contains null key :" + prefs.contains(null));
}
Editor e = prefs.edit();
e.putBoolean("run_once", true).commit();
e.putString(null, "I put a sting with null key").commit();
assertTrue("Contains null", prefs.contains(null));
PreferenceManager.getDefaultSharedPreferences( ctx); // exception
// NOT thrown here - why ? - apparently there is a static factory
// returning the instance it already constructed
// e.clear().commit(); // this eliminates the exception
}
}
exception :
W/ApplicationContext(): getSharedPreferences
W/ApplicationContext(): org.xmlpull.v1.XmlPullParserException: Map value without name attribute: string
W/ApplicationContext(): at com.android.internal.util.XmlUtils.readThisMapXml( XmlUtils.java:521)
W/ApplicationContext(): at com.android.internal.util.XmlUtils.readThisValueXml( XmlUtils.java:733)
W/ApplicationContext(): at com.android.internal.util.XmlUtils.readValueXml( XmlUtils.java:667)
W/ApplicationContext(): at com.android.internal.util.XmlUtils.readMapXml(XmlUtils. java:470)
W/ApplicationContext(): at android.app.ContextImpl.getSharedPreferences( ContextImpl.java:361)
W/ApplicationContext(): at android.preference.PreferenceManager. getDefaultSharedPreferences( PreferenceManager.java:348)
W/ApplicationContext(): at gr.uoa.di.android.helpers.test.XmlExceptionTest. testXmlException( XmlExceptionTest.java:18)
W/ApplicationContext(): at java.lang.reflect.Method.invokeNative(Native Method)
W/ApplicationContext(): at java.lang.reflect.Method.invoke(Method.java:521)
W/ApplicationContext(): at junit.framework.TestCase.runTest(TestCase.java:154)
W/ApplicationContext(): at junit.framework.TestCase.runBare(TestCase.java:127)
W/ApplicationContext(): at junit.framework.TestResult$1.protect(TestResult.java:106)
W/ApplicationContext(): at junit.framework.TestResult.runProtected(TestResult.java: 124)
W/ApplicationContext(): at junit.framework.TestResult.run(TestResult.java:109)
W/ApplicationContext(): at junit.framework.TestCase.run(TestCase.java:118)
W/ApplicationContext(): at android.test.AndroidTestRunner.runTest( AndroidTestRunner.java:169)
W/ApplicationContext(): at android.test.AndroidTestRunner.runTest( AndroidTestRunner.java:154)
W/ApplicationContext(): at android.test.InstrumentationTestRunner. onStart( InstrumentationTestRunner. java:520)
W/ApplicationContext(): at android.app.Instrumentation$InstrumentationThread.run( Instrumentation.java:1447)
Posted in SO here and in the relevant thread here - but still no answers
Any ideas ?
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
---
You received this message because you are subscribed to the Google Groups "Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home