5

基本上是设计问题——PreferenceActivity应该让它实现OnSharedPreferenceChangeListener还是应该在另一个类中定义这个功能——比如在内部类中?有什么理由让人们更喜欢另一种方法吗?

另外应该在哪里注册听众?我的意思是文档和常识onResume/onPause分别要求注册/取消注册,但是看到无数 注册,我只是想知道我是否遗漏了一些东西。 onCreate

此外,我不太确定取消注册失败(例如,这里可能不会调用取消注册,因为onStop不保证会调用)一定会导致泄漏。所以如果我有例如

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

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

最后 - 相同的考虑是否适用于OnPreferenceChangeListener

编辑:回到那个我看不到真正取消注册的方法OnPreferenceChangeListener- 我是盲人吗?

4

2 回答 2

1

除了个人喜好之外,我认为没有任何主要原因可以为听众偏爱特定的位置。实现Activity它,或者使用内部类——无论是匿名的还是非匿名的——都可以。

唯一的事情是,如果您没有使用像您这样的现有对象Activity作为侦听器,则需要保留对侦听器对象的引用。根据这个答案,如果您不这样做,它将被收集垃圾(因此实际上不会听任何东西)。


稍微研究一下源代码后,它似乎SharedPreferencesImpl使用 aWeakHashMap来包含已注册的侦听器(source,第 72-73 行、第 186-196 行),这意味着未能取消注册不会导致泄漏。

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

于 2013-12-10T11:44:18.767 回答
0

onPause在/中进行注册和取消注册onResume是很多额外的工作。

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

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

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

关于实现或不实现内部类,我倾向于使用匿名实现(如上所示),因为代码的清洁度更高——我不必为类名而烦恼,也不必键入更少的括号。然而,这真的是一个偏好的事情,所以做任何你觉得更好的事情。

于 2013-03-25T01:07:46.350 回答