Beware of Preference Default Values in XML
30 Mar 2015 | by cygeryVarious Preferences available in Android make the maintenance of settings straightforward. Even custom Preferences, e.g., for colors, can be created without much effort. By defining PreferenceScreens via XML, default values for each Preference can be set. However, parsing and type conversions of these default values can lead to unexpected and undesired results.
Android Preferences
Using a PreferenceActivity/PreferenceFragment and a PreferenceScreen, setup via XML, Preferences can be easily maintained and presented to the user.
Example
The following code snippet shows an example PreferenceScreen with an
EditTextPreference
(e.g., saved as res/xml/prefs.xml
):
The EditTextPreference has the key pref_key_edit_text
and the title EditText
.
In a PreferenceActivity, this PreferenceScreen can be loaded using the addPreferencesFromResource
method:
The stored Preference values can be accessed via SharedPreferences.
Preference Types and Underlying Types
Different Preferences use different types for their values. For example, EditTextPreference uses String, CheckBoxPreference boolean, and MultiSelectListPreference a set of Strings.
Default Values
A default value for a Preference can be set using the android:defaultValue
attribute:
Alternatively, a reference to a string can be used.
The Problem
Although EditTextPreference stores its value as a String, a default value set in the XML code isn’t simply handled as a String. Instead, during build, default values are parsed, e.g., as floats. This can have unexpected and, usually, undesired effects. Example:
The default value inf
is parsed as a float, converted to a String, and then stored as the Preference default value.
This results in a String value of Infinity
being stored instead of inf
.
Default values which can’t be parsed as a number are not affected.
Examples
Values Parsed as Float
Value set in XML | Resulting String value |
---|---|
inf | Infinity |
-inf | -Infinity |
nan | NaN |
+1 | 1.0 |
0.33333333 | 0.33333334 |
340282356779700000000000000000000000000. | 3.4028235E38 |
Values Parsed as Int
Value set in XML | Resulting String value | Comment |
---|---|---|
2147483647 | 2147483647 | max. int value |
2147483648 | -2147483648 | overflow (max. int value + 1) |
4294967296 | 0 | overflow (two times max. int value) |
340282356779700000000000000000000000000 | 872415232 | overflow |
01 | 1 | leading zeros are removed |
Bug Reports
There exist multiple bug reports about this issue.
Solution
Simple: Use a reference to a string for the default value:
The official guide also uses
references for String values in the examples. However, it does not mention what might happen when
default values (like inf
) are set directly, without using a String reference.