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
How to Update a Single Row in a Listview
How to Use the Animation Framework Inside the Canvas
Call an Activity Method from a Fragment
How to Change Current Theme At Runtime in Android
Update Data in Listfragment as Part of Viewpager
How to Detect Orientation Change in Layout in Android
How to Display Count of Notifications in App Launcher Icon
Get Root View from Current Activity
Android - How to Override the "Back" Button So It Doesn't Finish() My Activity
How to Exit from the Application and Show the Home Screen
How to Start a Service When .Apk Is Installed For the First Time
How to Find the Latitude and Longitude from Address
How to Create a Release Signed Apk File Using Gradle
Android: Alternate Layout Xml For Landscape Mode
Listview Inside Scrollview Is Not Scrolling on Android
Android Studio Adds Unwanted Permission After Running Application on Real Device