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.

Reply via email to