Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android : Where should a OnSharedPreferenceChangeListener be defined/registered

Design question basically - having a PreferenceActivity should one make it implement OnSharedPreferenceChangeListener or should one define this functionality in another class - say in an inner class ? Is there some reason one would prefer the one over the other approach ?

Also where should one register the listener ? I mean the docs and common sense dictate to register/unregister in onResume/onPause respectively but having seen a zillion registrations in onCreate I just wonder if I am missing something.

Also I am not quite certain if a failure to unregister (so here for instance unregistering may not be called as onStop is not guaranteed to be called) would necessarily lead to a leak. So if I have for instance

class MyPref extends PreferenceActivity implements
            OnSharedPreferenceChangeListener {
    SharedPreferences sharedPreferences;
    // init sharedPreferences
    onStart(){
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);
    }
    // no unregistration
}

Would this leak the MyPref instance once I go back to one of my other activities ?

Lastly - would the same considerations apply to OnPreferenceChangeListener ?

Edit : coming back to that I see no way to actually unregister the OnPreferenceChangeListener - am I blind ??

like image 621
Mr_and_Mrs_D Avatar asked Nov 13 '22 08:11

Mr_and_Mrs_D


1 Answers

I don't believe there are any major reasons to favour a particular location for the listener, apart from personal preference. Having the Activity implement it, or using an inner class - either anonymous or not - are all OK.

The only thing is, if you're not using an existing object like your Activity as the listener, you'll need to keep a reference to the listener object. As per this answer it will get garbage collected (and thus not actually listen to anything) if you don't.


Having dug into the source a bit, it seems SharedPreferencesImpl uses a WeakHashMap to contain registered listeners (source, lines 72-73, 186-196), meaning that failing to unregister won't cause a leak.

As you say, the docs do recommend using onResume() / onPause(); this is probably nothing to do with leaks, but instead to prevent background apps doing unnecessary processing - so still worth following!

like image 152
just me Avatar answered Nov 15 '22 13:11

just me