Android:应该在哪里定义/注册OnSharedPreferenceChangeListener

时间:2013-03-24 21:59:21

标签: android android-preferences

基本上设计问题 - 拥有PreferenceActivity应该让它实现OnSharedPreferenceChangeListener还是应该在另一个类中定义这个功能 - 比如在内部类中?是否有人会更倾向于采用另一种方法?

还应该在哪里注册听众?我的意思是the docs和常识要求分别在onResume/onPause注册/取消注册,但在onCreate中看过a zillion registrations我只是想知道是否我错过了什么。

此外,我不确定是否未注册(因此here未注册,因此onStop无法保证调用{{3}})必然会导致泄漏。所以如果我有例如

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

一旦我回到其他一项活动,这会泄漏MyPref实例吗?

最后 - 同样的注意事项适用于OnPreferenceChangeListener吗?

编辑:回到那里我看不到实际取消注册OnPreferenceChangeListener - 我是不是真的?

2 个答案:

答案 0 :(得分:1)

除了个人偏好之外,我不认为有任何主要理由支持听众的特定位置。让Activity实现它,或者使用内部类 - 无论是否匿名 - 都可以。

唯一的问题是,如果您没有使用像Activity这样的现有对象作为侦听器,则需要保留对侦听器对象的引用。根据{{​​3}},如果不这样做,它将收集垃圾(因此实际上不会收听任何内容)。


稍微挖掘了一下源,似乎SharedPreferencesImpl使用WeakHashMap来包含已注册的侦听器(this answer,第72-73行,186-196行),这意味着未能取消注册不会导致泄密。

正如您所说,文档建议使用onResume() / onPause();这可能与泄漏无关,而是为了防止后台应用程序进行不必要的处理 - 所以仍值得关注!

答案 1 :(得分:0)

onPause / onResume中进行注册和取消注册是一项无用的额外工作。

您可以将监听器的匿名实现作为您的类的一部分,如下所示:

[class level]
...
OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener () {
    onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        // your code here
    }
};
...
[class level]

然后在适用的地方进行设置。如果这样做,则不会将您的侦听器重新创建为onPause / onResume之间的其他对象(除非您的应用程序被杀,并且您的Activity子类必须再次加载)因此,分配它是没有意义的,因为你总是会引用同一个对象。另一方面,如果你的应用程序被杀,那么onCreate将再次被调用。

关于实现内部类,或者不实现内部类,我倾向于使用匿名实现(如上所示),因为代码的清洁度得到了提高 - 我不必费心去做类名并且必须输入更少的括号。然而,这真的是一种偏好,所以做你觉得更好的事情。

相关问题