来自本指南的首选项,
警告:当调用registerOnSharedPreferenceChangeListener()时,首选项管理器当前不存储对侦听器的强引用。必须将强引用存储到侦听器,否则将容易受到垃圾收集的影响。 我们建议您在对象的实例数据中保留对侦听器的引用,只要您需要侦听器,该对象就会存在。
发布于 2016-03-11 09:09:55
简单地说- WeakReference是一个java概念/类。对象,这些对象仅使用弱引用get在GC传递中收集垃圾。
另一方面,强引用/您一直使用的引用(例如Integer a= 20;)不允许GC收集/释放对象。
因此,在您的示例中,假设您向首选项管理器注册了一个OnSharedPreferenceChangeListener,则首选项管理器将将其存储为一个非强引用(可能是一个弱引用)。
prefs.registerOnSharedPreferenceChangeListener(
//anonymous object, you don't hold the reference to the listener you create - this is susceptible to get garbage collected
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// listener implementation
}
});这意味着,每当GC罢工时,侦听器对象都将被收集起来,因为在任何地方都没有对侦听器object.As的强引用--结果,首选项管理器将丢失它保存给您注册的侦听器的弱引用,此后您将不会收到任何首选项更改回调。
但是-如果您自己存储对侦听器的强引用,在代码中的某个地方,它将使GC跳过对侦听器对象的收集/释放,因为至少有一个对该对象的强引用。这将使您继续接收来自首选项管理器的回调。
public class ABC extends Activity{
SharedPreferences.OnSharedPreferenceChangeListener listener; // this object will last until the enclosing activity is destroyed.
...onCreate(Bundle b){
prefs.registerOnSharedPreferenceChangeListener(
// Create a **strong** reference to the listener
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// listener implementation
}
});
}发布于 2018-03-09 10:35:50
@Vinay的答案中的代码帮助我解决了文档警告存储对onSharedPreferenceChangeListener的“强引用”的问题。
谁知道“强引用”只是一个“正常”变量声明。
因此,请按如下方式声明侦听器:
SharedPreferences.OnSharedPreferenceChangeListener listener;。
并付诸实施。
我希望能在两个方面提供更多帮助:
(1)给出一个稍完整的例子。
(2)如果侦听器有点复杂的话,“解除杂波”onCreate。
(1)略为完整的例子:
public class MainActivity extends Activity
{
SharedPreferences sp;
OnSharedPreferenceChangeListener listener; // will last until activity is destroyed
@Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sp = getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener
(
listener = new OnSharedPreferenceChangeListener() // strong reference
{
@Override public void onSharedPreferenceChanged(SharedPreferences shpf, String key)
{
SharedPreferences.Editor editor = shpf.edit();
switch(key)
{
case PREF_SHORTEST_WORD:
prefShortestWord = parseInt(shpf.getString(PREF_SHORTEST_WORD, "2"));break;
case PREF_LONGEST_WORD:
prefLongestWord = parseInt(shpf.getString(PREF_LONGEST_WORD, "15")); break;
case PREF_MAX_MATCHES:
prefMaxMatches = parseInt(shpf.getString(PREF_MAX_MATCHES, "50")); break;
} // switch
editor.apply();
} // onSharedPrefereeceChanged
} // onSharedPreferenceChangeListener
); // registerJnSharedPreferenceChangeListener
...
} // onCreate
...
} // MainActivity但是,如果上面的侦听器变得比上面显示的3种情况复杂得多,那么onCreate可能看起来“杂乱无章”,代码可以放在其他地方更好。
(2)整洁的onCreate
public class MainActivity extends Activity
{
SharedPreferences sp;
// don't declare here: OnSharedPreferenceChangeListener listener;
@Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sp = getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(listener); // define listener later
...
} // onCreate我们肯定有一个上面“整洁”的onCreate。
但是在哪里定义listener呢?作为MainActivity末尾的私有对象
... // end of MainActivity objects except one:
private OnSharedPreferenceChangeListener listener =
new OnSharedPreferenceChangeListener() // strong reference
{
@Override public void onSharedPreferenceChanged(SharedPreferences shpf, String key)
{
SharedPreferences.Editor editor = shpf.edit();
switch(key) // moment of truth
{
case PREF_SHORTEST_WORD:
prefShortestWord = parseInt(shpf.getString(PREF_SHORTEST_WORD, "2")); break;
case PREF_LONGEST_WORD:
prefLongestWord = parseInt(shpf.getString(PREF_LONGEST_WORD, "15")); break;
case PREF_MAX_MATCHES:
prefMaxMatches = parseInt(shpf.getString(PREF_MAX_MATCHES, "50")); break;
} // switch
editor.apply();
} // onSharedPrefereeceChanged
}; // onSharedPreferenceChangeListener
} // MainActivity让听者尽可能长时间。这是“让开”。
https://stackoverflow.com/questions/35935936
复制相似问题