"Starting over" with shared prefs content when something goes wrong --
looks to me like a feature, and a useful one: sometimes storage goes
bad, files get corrupted, etc.

Being able to put null keys into shared prefs, and it triggering the
corruption handing code path later -- looks like a bug to me.

Just my two somethings...

-- K

2013/10/31 Palmer Eldritch <the.u...@gmail.com>:
> 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 <the....@gmail.com>
>> 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 <the....@gmail.com>
>> >> 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 android-d...@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscr...@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+unsubscr...@googlegroups.com.
>> > 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 android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@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+unsubscr...@googlegroups.com.
> 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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to