pwittchen / prefser

Wrapper for Android SharedPreferences with object serialization and RxJava Observables
Apache License 2.0
229 stars 26 forks source link

Boolean default value returns a String #22

Closed JulienDev closed 9 years ago

JulienDev commented 9 years ago

Hi,

Is there a reason why the default value of a Boolean does not return true or false but a String containing the value? In my opinion it must returns a boolean to avoid crashes.

Thanks

pwittchen commented 9 years ago

Hi,

In this library, all values are stored as Strings, because I wanted to use single get(...) method for all types of data. When you want to read value as a Boolean, you should define returned type via Java Generics. Finally, SharedPreferences are stored in an XML file, so some conversion still needs to be done and it's just one of the approaches.

When you read Boolean data in the following way:

Boolean value = prefser.get("key", Boolean.class); 
Boolean value = prefser.get("key", Boolean.class, true); // with default value

or

boolean value = prefser.get("key", Boolean.class);
boolean value = prefser.get("key", Boolean.class, true); // with default value

You will get Boolean or primitive boolean instead of String.

If we do it in another way, we should define several methods for each type of data like: getBoolean(key), getString(key), getInt(key), getArrayOfStrings(key) and so on. This kind of approach is done in regular SharedPreferences. I just decided to do it in a different way to keep single get(key, type) method.

It's important to use this library properly. That's why I provided many examples in README.md file to show how to use it for different types of data. In addition, you can look at unit tests, where you can view more examples of usage of the library.

yurike commented 9 years ago

The problem is when I read Boolean data in the way like: boolean flag = prefser.get("mykey", boolean.class, false); or Boolean flag = prefser.get("mykey", Boolean.class, false);

I get a RunTimeException like: Caused by: java.lang.ClassCastException: java.lang.Boolean at android.app.ContextImpl$SharedPreferencesImpl.getString(ContextImpl.java:3040) at com.github.pwittchen.prefser.library.Prefser.get(Prefser.java:178) at... my line mentioned above

Possibly this is somehow connected to the fact that the value is changed using standard CheckBoxPreference in Preferences screen: <CheckBoxPreference android:key="mykey" android:title="@string/keyTitle" android:defaultValue="false" />

pwittchen commented 9 years ago

Thanks @yurike. That's more detailed description and now I know where to start fixing this issue. I'll take a closer look on this problem.

carstenbaumhoegger commented 9 years ago

I get the same RunTimeException only with int's: Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at android.app.SharedPreferencesImpl.getString(SharedPreferencesImpl.java:224) at com.github.pwittchen.prefser.library.Prefser$6.get(Prefser.java:295) at com.github.pwittchen.prefser.library.Prefser.get(Prefser.java:173)

I don't access a standard Preference from a Preference screen.

pwittchen commented 9 years ago

Thanks for reporting this issue @carstenbaumhoegger. I'll take a look on that.

pwittchen commented 9 years ago

This bug is fixed in PR #24. I've updated code responsible for reading and saving data. Now, it uses built-in methods from Android SharedPreferences when it's possible. I've added exemplary app with PreferenceActivity to the repository and it works correctly with updated version of the library. You can also take a look at updated README.md file to see what's changed. This fix will be available in version 1.0.4 of the library, which should be released in a few days. I'll add information about changes to release notes of v. 1.0.4. If you still will have some problems with reading or saving data, please open new issue and we'll resolve it.

pwittchen commented 9 years ago

New version of the library (1.0.4) with fixed bug is already available on Maven Central Repository.