Android 对对象的“强”引用是什么意思?为什么要将对OnSharedPreferenceChangeListener的引用存储在对象的数据中?

Android 对对象的“强”引用是什么意思?为什么要将对OnSharedPreferenceChangeListener的引用存储在对象的数据中?,android,sharedpreferences,listener,android-preferences,android-sharedpreferences,Android,Sharedpreferences,Listener,Android Preferences,Android Sharedpreferences,从偏好来看 警告:调用RegisterOnSharedReferenceChangeListener时 首选项管理器当前未存储对的强引用 听众。必须存储对侦听器的强引用, 否则它将容易受到垃圾收集的影响 我们建议您在实例数据中保留对侦听器的引用 只要您需要侦听器,对象就会存在 这里的强引用,而不仅仅是引用,是什么意思? 他们建议在实例中保留引用 对象的数据。这意味着还有其他方法来保持 静态变量?中的引用?。所以问题是 为什么他们建议在对象的实例数据中保留引用? 简单来说— 是一个java概念/类

从偏好来看

警告:调用RegisterOnSharedReferenceChangeListener时 首选项管理器当前未存储对的强引用 听众。必须存储对侦听器的强引用, 否则它将容易受到垃圾收集的影响

我们建议您在实例数据中保留对侦听器的引用 只要您需要侦听器,对象就会存在

这里的强引用,而不仅仅是引用,是什么意思? 他们建议在实例中保留引用 对象的数据。这意味着还有其他方法来保持 静态变量?中的引用?。所以问题是 为什么他们建议在对象的实例数据中保留引用? 简单来说— 是一个java概念/类。仅使用弱引用引用的对象在GC过程中被垃圾收集

另一方面,强引用/您一直使用的引用,例如整数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触发时,侦听器对象将被收集,因为侦听器对象的任何地方都没有强引用。因此,首选项管理器将丢失它对您注册的侦听器的弱引用,并且此后您将不会得到任何首选项更改回调

但是-如果您自己在代码中的某个地方存储对侦听器的强引用,它将使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
      }
    });
}

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

谁知道强引用只是一个普通变量声明呢

因此,像这样声明侦听器:

SharedReferences.OnSharedPreferenceChangeListener

并加以实施

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

1给出一个更完整的例子

2如果侦听器有点复杂,则在创建时保持整洁

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上面

但在哪里定义侦听器呢?作为MainActivity结束时的私有对象:

尽可能长时间地倾听。这太离谱了。

它不应该是整数a=20而不是整数a吗?我不认为强/弱引用适用于原语。
    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
... // 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