Why could one permit null keys - actually *one *null key - to have afterwards* all the preferences cleared due to an exception *? Given that the prefs are a persistence mechanism. No it is at least an oversight - except if I am missing something NB - I am talking about the default shared preferences - but all shared preferences are the same behind the scenes
On Wednesday, October 30, 2013 10:27:03 PM UTC+2, Kristopher Micinski wrote: > > I would honestly suspect that it's "meant" to be this way, and perhaps > the documentation is buggy. If you want, posting a bug report might > get some action by Android devs, if none of them respond here. > > Kris > > > On Wed, Oct 30, 2013 at 3:39 PM, Palmer Eldritch > <[email protected]<javascript:>> > wrote: > > I did not mean to complain at Nobu - sorry if I sounded harsh :) > > > > I just wanted to point out that my question was not so much what happens > but > > why - and also raise awareness to this buggy and unintuitive behavior- > or > > maybe have someone explain why this is so. > > > > Should we post a bug report ? > > > > > > On Wednesday, October 30, 2013 8:23:46 PM UTC+2, Kristopher Micinski > wrote: > >> > >> Your question seems more to deal with intention rather than > >> complaining. I believe that Nobu's response was merely interpreting > >> the implementation and trying to interpret it, so there's no use in > >> trying to complain at him for providing a guess at something he didn't > >> even write. > >> > >> kris > >> > >> > >> On Wed, Oct 30, 2013 at 2:02 PM, Palmer Eldritch <[email protected]> > >> wrote: > >> > > >> > 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 > >> >> > >> >> > >> >> 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 > > >> > > >> >> > >> >> > >> >> 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 > > [email protected]<javascript:> > > To unsubscribe from this group, send email to > > [email protected] <javascript:> > > 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 [email protected] <javascript:>. > > For more options, visit https://groups.google.com/groups/opt_out. > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] 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 [email protected]. For more options, visit https://groups.google.com/groups/opt_out.

