Sharedpreferences.Onsharedpreferencechangelistener Not Being Called Consistently

SharedPreferences.onSharedPreferenceChangeListener not being called consistently

This is a sneaky one. SharedPreferences keeps listeners in a WeakHashMap. This means that you cannot use an anonymous inner class as a listener, as it will become the target of garbage collection as soon as you leave the current scope. It will work at first, but eventually, will get garbage collected, removed from the WeakHashMap and stop working.

Keep a reference to the listener in a field of your class and you will be OK, provided your class instance is not destroyed.

i.e. instead of:

prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// Implementation
}
});

do this:

// Use instance field for listener
// It will not be gc'd as long as this instance is kept referenced
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// Implementation
}
};

prefs.registerOnSharedPreferenceChangeListener(listener);

The reason unregistering in the onDestroy method fixes the problem is because to do that you had to save the listener in a field, therefore preventing the issue. It's the saving the listener in a field that fixes the problem, not the unregistering in onDestroy.

UPDATE: The Android docs have been updated with warnings about this behavior. So, oddball behavior remains. But now it's documented.

SharedPreferences.OnSharedPreferenceChangeListener not called when ListPreference changes value

You are using a non-default preferences in SettingsActivity but you aren't indicating the PreferenceManager which shared preference should use.

The OnSharedPreferenceChangeListener is registered to the SharedPreferences - SharedPrefFile - which is not the default one.

In the SettingsFragment in the OnCreate before adding the preferences try setting the SharedPreferencesName. Something like this:

 PreferenceManager prefMgr = getPreferenceManager();
prefMgr.setSharedPreferencesName(getString(R.string.pref_file));
prefMgr.setSharedPreferencesMode(MODE_WORLD_READABLE);

onsharedpreferencechangelistener not work in android app

I solved my problem:

  public class MainActivity  extends Activity {

SharedPreferences pref;
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {

@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if(key.equals("demopref"))
Toast.makeText(getApplicationContext(),"Hello2---"+key,Toast.LENGTH_LONG).show();

}
};

@SuppressWarnings("deprecation")

int i=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

////////////////////////////////////////

final Button sosBtn = (Button) findViewById(R.id.button);
sosBtn.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
SharedPreferences.Editor editor = pref.edit();
editor.putString("demopref","HI"+String.valueOf(i));
i++;
editor.commit();
/////////////////////////////////

}
});



}

@Override
protected void onResume() {
pref.registerOnSharedPreferenceChangeListener(listener);

super.onResume();
}

@Override
protected void onPause() {
pref.unregisterOnSharedPreferenceChangeListener(listener);

super.onPause();
}


}

onSharedPreferenceChanged not fired if change occurs in separate activity?

The OnSharedPreferenceChangeListener gets garbage collected in your case if you use an anonymous class.

To solve that problem use the following code in PreferenceActivity to register and unregister a change listener:

public class MyActivity extends PreferenceActivity implements
OnSharedPreferenceChangeListener {

@Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key)
{
// do stuff
}

Furthermore be aware that the listener only gets called if the actual value changes. Setting the same value again will not fire the listener.

see also SharedPreferences.onSharedPreferenceChangeListener not being called consistently

OnSharedPreferenceChangeListener not getting fired

in onCreate you register your listener

prefs.registerOnSharedPreferenceChangeListener(listener);

you can unregister it on onDistry

if you do it like this , this should work !

listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// your code
}
};

prefs.registerOnSharedPreferenceChangeListener(listener);

OnSharedPreferenceChangeListener not always working

I fixed it by changing

SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener(){
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){

into

listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {

and changing listener into a private variable. I also added the following @Override functions:

    @Override
public void onDestroy(){
super.onDestroy();
prefs.unregisterOnSharedPreferenceChangeListener(listener);
}

@Override
public void onPause(){
super.onPause();
prefs.unregisterOnSharedPreferenceChangeListener(listener);
}

@Override
public void onResume(){
super.onResume();
prefs.registerOnSharedPreferenceChangeListener(listener);
}

Now it works every time.

First time commit didn't raise onSharedPreferenceChanged

I hope it will help someone:

The problem was that we registered it in onCreate method. It is working if you will create it in onResume method.

Also, please, look on this answer for common problem with SharedPreference: SharedPreferences.onSharedPreferenceChangeListener not being called consistently

Android Shared preference change listener not working even with a global refernce of listener

It seems from this post that what I am trying to do is unsupported in Android. WORLD_READABLE flag for SharedPreferences does not support multi-thread support which might be causing the inconsistencies. In the Android developer site also it is mentioned that multiple process support for SharedPreferences is not available for WORLD_READABLE preferences.

OnSharedPreferenceChangeListener not firing in MainActivity?

In MyDialogFragment the listener is defined in class scope - will live as long as the class. In your onResume() the listener is defined as a local variable in onResume() so when onResume() returns the listener is out of scope and for reasons explained in SharedPreferences.onSharedPreferenceChangeListener not being called consistently it is garbage collected. Notice that in this answer we have listener = new SharedPreferences.OnSharedPreferenceChangeListener() { //etc while you do OnSharedPreferenceChangeListener listener = new // etc, so you define a local variable.



Related Topics



Leave a reply



Submit