9

我已经阅读了这篇有用的帖子:

SharedPreferences.onSharedPreferenceChangeListener 没有被一致地调用

但是我没有运气。我正在尝试创建一个在服务中运行的 OnSharedPreferenceChangeListener。一切都正确实施,但并不总是触发侦听器。

public MyServiceOne extends Service {

    public SharedPreferences mSharedPreferences;

    // Listener defined by anonymous inner class.
    public OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {        

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            Log.d("debug", "A preference has been changed");            
        }
    };

    @Override
    public void onCreate() {            
        mSharedPreferences = getSharedPreferences(MySharedPreferences.NAME, Context.MODE_PRIVATE);
        mSharedPreferences.registerOnSharedPreferenceChangeListener(mListener);
    }

    @Override   
    public void onDestroy() {
        super.onDestroy();
        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(mListener);
    }
}

更新

问题源于一个我没有提到的事实。我正在运行两项服务,当在 MyService2 中进行共享首选项更改时,不会触发任何内容。在清单中,我定义了要在不同进程中运行的服务。有没有办法使这项工作?

4

3 回答 3

10

在获得了一些 Android 经验后,我回来回答这个问题,并帮助其他在这种情况下遇到问题的人。

OnSharedPreferenceChangeListener 的实现是正确的。问题在于清单和应用程序架构。由于服务在不同的进程中运行,Android 为每个服务创建了不同的 Dalvik 虚拟机,因此它们不会“听到”彼此的监听器。

这只是糟糕的设计——实现运行两个并发服务的更好方法是创建一个服务,将每个“服务”线程化以同时运行。这样他们就可以共享相同的堆,从而共享相同的对象和侦听器

如果有人决定使用两个服务,他们可以创建一个 BroadcastReceiver 来捕获需要更改偏好的意图 - 或通过套接字进行通信。还有一些方法可以使用 ContentProvider 来做到这一点(请永远不要这样做)。但同样,如果设计好,就没有任何理由这样做。

于 2012-03-01T14:38:08.070 回答
0

为什么不让您的服务实施OnSharedPreferenceChangeListener

这样它就不是一个匿名的内部类,所以它不会被垃圾收集,你仍然可以在服务中做任何你想做的事情。

于 2011-11-01T14:37:39.227 回答
0

我知道这个线程很旧。但是有没有人用 MODE_MULTI_PROCESS 试过这个?

MODE_MULTI_PROCESS

于 2014-08-31T02:13:39.557 回答