基本上设计问题 - 拥有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
- 我是不是真的?
答案 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
将再次被调用。
关于实现内部类,或者不实现内部类,我倾向于使用匿名实现(如上所示),因为代码的清洁度得到了提高 - 我不必费心去做类名并且必须输入更少的括号。然而,这真的是一种偏好,所以做你觉得更好的事情。