"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 <[email protected]>:
> 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]>
>> 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]
>> > 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.
>
> --
> 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.

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

Reply via email to