如果更改发生在单独的活动中,onSharedPreferenceChanged不会被触发?

我在我的主要活动中实现了onSharedPreferenceChanged

如果我在主要活动中更改首选项,则会触发我的活动。

如果通过我的首选项屏幕( PreferenceActivity )更改首选项,则当首选项发生更改时,我的事件不会触发(因为它是一个单独的活动并单独引用sharedPreferences?)

有人build议我应该如何克服这种情况?

谢谢!

编辑1:我试图添加事件处理正确的在我的喜好活动,但它永远不会触发。 在我的偏好活动的onCreate过程中调用以下方法。 当我更改值时,它从不打印消息( msg()Log.d的包装)。

 private void registerChangeListener () { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); sp.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener () { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { msg (" ***** Shared Preference Update ***** "); Intent i = new Intent(); i.putExtra("KEY", key); i.setAction("com.gtosoft.dash.settingschanged"); sendBroadcast(i); // TODO: fire off the event } }); } 

如果您使用匿名类,则OnSharedPreferenceChangeListener会在您的案例中收集垃圾。

要解决这个问题,请使用PreferenceActivity的以下代码来注册和取消注册更改侦听器:

 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 } 

另外请注意,如果实际值发生变化,监听器才会被调用。 再次设置相同的值不会触发侦听器。

另请参阅SharedPreferences.onSharedPreferenceChangeListener不被一致调用

这是因为垃圾收集器。 其作品只有一次。 那么这个参考被收集为垃圾。 所以为侦听器创build实例字段。

 private OnSharedPreferenceChangeListener listner; listner = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { //implementation goes here } }; prefs.registerOnSharedPreferenceChangeListener(listner); 

我和其他许多人一样来到了这里,因为当我把布尔变化从truefalse ,反之亦然时,我的听众不会被解雇。

经过多次阅读和重构,切换contexts/inner classes/privates/static/等,我意识到我(愚蠢)的错误:

onSharedPreferenceChanged 只有在事物发生变化时才被调用。 只要。 永远。

在我的testing过程中,我总是一直点击同一个button,所以一直都是一样的布尔值,所以并没有改变。

希望这可以帮助别人!

避免这个问题的另一种方法是让你的活动成为监听器类。 由于只有一个具有独特名称的覆盖方法,你可以这样做:

 public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sharedPreferences.registerOnSharedPreferenceChangeListener(this); ... } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { ... } } 

注意最初的问题是关于在PreferenceActivity中监听设置更改的MainActivity。 提问者然后添加了一个“EDIT1”,并将问题改为在PreferenceActivity本身中进行侦听。 这比前者容易,似乎是所有的答案假设。 但是,如果你仍然想要以前的场景呢?

那么,它也可以工作,但不要使用OnResume()和OnPause()来注册和注销侦听器。 这样做会导致监听器无效,因为用户在使用PreferenceActivity时离开了MainActivity(当您考虑这一点时,这是有意义的)。 所以它会起作用,但是即使用户没有使用它,你的MainActivity仍然会在后台监听。 那种浪费资源不是吗? 所以有另一种解决scheme似乎工作,只需添加一个方法到OnResume()重新读取所有的偏好。 这样,当用户在PreferenceActivity中完成编辑首选项时,MainActivity将在用户返回时将其选中,并且根本不需要侦听器

有人请让我知道,如果他们看到这种方法的问题。

为什么不在只有首选项可能更改的其他活动中添加onSharedPreferenceChanged

在阅读由第一个应用程序共享的Word可读数据时,我们应该

更换

 getSharedPreferences("PREF_NAME", Context.MODE_PRIVATE); 

 getSharedPreferences("PREF_NAME", Context.MODE_MULTI_PROCESS); 

在第二个应用程序中获取更新值在第二个应用程序

垃圾收集器将擦除这个…你应该考虑使用一个应用程序上下文来代替…或者只是在应用程序启动时添加代码…然后将监听器添加到应用程序上下文中…