首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >什么是对对象的“强”引用,为什么我们要将对OnSharedPreferenceChangeListener的引用存储在对象的数据中?

什么是对对象的“强”引用,为什么我们要将对OnSharedPreferenceChangeListener的引用存储在对象的数据中?
EN

Stack Overflow用户
提问于 2016-03-11 08:59:48
回答 2查看 939关注 0票数 2

来自本指南的首选项,

警告:当调用registerOnSharedPreferenceChangeListener()时,首选项管理器当前不存储对侦听器的引用。必须将引用存储到侦听器,否则将容易受到垃圾收集的影响。 我们建议您在对象的实例数据中保留对侦听器的引用,只要您需要侦听器,该对象就会存在。

  1. 它们在这里所说的强引用是什么意思,而不是(只是a)引用?
  2. 他们建议将引用保留在对象的实例数据中。这意味着还有其他保持引用的方法(在静态变量中?)。所以问题是,为什么建议保留对象的实例数据中的引用?
EN

回答 2

Stack Overflow用户

发布于 2016-03-11 09:09:55

简单地说- WeakReference是一个java概念/类。对象,这些对象仅使用弱引用get在GC传递中收集垃圾。

另一方面,强引用/您一直使用的引用(例如Integer a= 20;)不允许GC收集/释放对象。

因此,在您的示例中,假设您向首选项管理器注册了一个OnSharedPreferenceChangeListener,则首选项管理器将将其存储为一个非强引用(可能是一个弱引用)。

代码语言:javascript
运行
复制
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跳过对侦听器对象的收集/释放,因为至少有一个对该对象的强引用。这将使您继续接收来自首选项管理器的回调。

代码语言:javascript
运行
复制
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
      }
    });
}
票数 4
EN

Stack Overflow用户

发布于 2018-03-09 10:35:50

@Vinay的答案中的代码帮助我解决了文档警告存储对onSharedPreferenceChangeListener的“强引用”的问题。

谁知道“强引用”只是一个“正常”变量声明。

因此,请按如下方式声明侦听器:

SharedPreferences.OnSharedPreferenceChangeListener listener;

并付诸实施。

我希望能在两个方面提供更多帮助:

(1)给出一个稍完整的例子。

(2)如果侦听器有点复杂的话,“解除杂波”onCreate

(1)略为完整的例子:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
    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末尾的私有对象

代码语言:javascript
运行
复制
... // 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

让听者尽可能长时间。这是“让开”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35935936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档