view.getViewTreeObserver().addOnGlobalLayoutListener泄漏片段

mar*_*689 13 android memory-leaks android-fragments

当我使用它GlobalLayoutListener来查看softKeyboard是否被打开时,片段在被销毁后不再是garbageCollected.

我所做的:

  • 我删除了onDestroy()片段中的监听器
  • 我的监听器设置为nullonDestroy()
  • 我将观察到的视图设置为null onDestroy()

仍在泄漏碎片.

有没有人有类似的问题,并知道它的修复?

我的onDestroy:

   @Override
public void onDestroy(){
    Log.d(TAG , "onDestroy");

    if(Build.VERSION.SDK_INT < 16){
        view.getViewTreeObserver().removeGlobalOnLayoutListener(gLayoutListener);
    }else{
        view.getViewTreeObserver().removeOnGlobalLayoutListener(gLayoutListener);
    }

    view = null;
    gLayoutListener = null;



    super.onDestroy();
    }
Run Code Online (Sandbox Code Playgroud)

The*_*oid 31

我相信在onDestroy()中强烈删除由View对象引用的Listener 为时已晚.这种覆盖方法发生在onDestroyView()之后,它应该"......清理与其View相关的资源".您可以使用相同的代码onStop().虽然我没有使用这种技术.

我可以建议这个代码,我使用它而没有任何调试器问题.

// Code below is an example. Please change it to code that is more applicable to your app.
final View myView = rootView.findViewById(R.id.myView);
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @SuppressLint("NewApi") @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {

        // Obtain layout data from view...
        int w = myView.getWidth();
        int h = myView.getHeight();
        // ...etc.

        // Once data has been obtained, this listener is no longer needed, so remove it...
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            myView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        else {
            myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 由于getViewTreeObserver用于布局,通常只需要很短的时间就可以使用此监听器.因此,立即删除听众.
  • 第二次调用removeOnGlobalLayoutListener()应由Studio划掉,因为它在JELLY_BEAN之前不可用.
  • @SuppressWarnings("deprecation")如果您使用的是Android Studio,则无需使用Pragma代码.
  • 代码myView = rootView.findViewById(R.id.myView);可能需要更改为适用于您的应用或情境的更适用的代码.

  • 干杯你的帮助!:) 顺便说一句,达到 1,000 SO 积分是我生命中最伟大的时刻之一 - 甚至超过了我通过公路自行车水平测试的那一天。 (2认同)