[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?
I posted an issue which is fixed: http://code.google.com/p/android/issues/detail?id=63463 On Wednesday, October 30, 2013 12:48:12 PM UTC+2, MrMrs D 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 herehttp://stackoverflow.com/questions/19610569/android-sharedpreferences-null-keys-values-and-sets-corner-casesand in the relevant thread here http://stackoverflow.com/a/19621603/281545 - 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+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.
[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?
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. 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. 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. 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 herehttp://stackoverflow.com/questions/19610569/android-sharedpreferences-null-keys-values-and-sets-corner-casesand in the relevant thread here http://stackoverflow.com/a/19621603/281545 - 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+unsubscr...@googlegroups.com
[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 herehttp://stackoverflow.com/questions/19610569/android-sharedpreferences-null-keys-values-and-sets-corner-cases) 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 documentedhttp://developer.android.com/guide/topics/data/data-storage.html#prefpersistence 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)
Re: [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?
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.u...@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
Re: [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?
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.comjavascript: 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
Re: [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?
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.u...@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
Re: [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?
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.comjavascript: 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();
Re: [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?
I agree it's an oversight, and that at the very least there should be something in the documentation to give the semantics in this case. kris On Wed, Oct 30, 2013 at 4:39 PM, Palmer Eldritch the.u...@gmail.com wrote: 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();
Re: [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?
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,