I’ve just released my first live wallpaper for android. I bug tested it on my phone and several friends phones without finding any problems, but apparently on some devices it’s getting stuck in a recursive loop and causing a stack overflow error when the user tries to change settings.
I believe the problem is occurring because I have certain “theme” settings which need to change several other persisted values. For example one theme will set a default color, speed, background, etc. It seems that when I persist these values programmatically with Editor.commit(), it’s calling onSharedPreferenceChanged again, and again, and again…
Since this is a live wallpaper, I have a preview running behind the transparent preference screen, and I need it to reflect the settings changes as they’re made. I also need the sliders/color pickers/list preferences to reflect changes made both by the user directly, and programmatically when a “theme” is selected. The easiest way to do this seemed to be to change them with a preference editor in onSharedPreferenceChanged, and indeed, this works on many devices.
What can I do to make it work on all devices?
Here’s the relevant code:
public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
{
if(key != null)
{
SharedPreferences.Editor editor = prefs.edit();
hue = prefs.getInt("color", 0);
BG_COLOR = prefs.getInt("background_color", 0);
//etc...
if(key.matches("plasma_set"))
{
plasmaAtlasName = atlasName;
editor.putString("atlasName", atlasName);
//load each bolt set with defalut values
if(plasmaAtlasName.equals("plasmaAtlas11"))
{
hue = 180;
editor.putInt("speed", 10);
editor.putInt("bolt_density", 2);
BG_COLOR = 0;
editor.putInt("background_color", BG_COLOR);
editor.putInt("color", hue);
}
if(plasmaAtlasName.equals("plasmaAtlas9"))
{
hue = 330;
editor.putInt("speed", 10);
editor.putInt("bolt_density", 2);
BG_COLOR = 0;
editor.putInt("background_color", BG_COLOR);
editor.putInt("color", hue);
}
//etc...
}
editor.commit();
}
}
Ok, I figured it out. It was a simple matter of unregistering the listener before calling Editor.commit() and then registering it again afterward.