Crash-fix-1:PhoneWindow$DecorView{29b8ae38 V.E..... R.....I. 0,0-1160,607} not attached to window ma

最近开始对APP上的Crash进行对应,发现有好多常见的问题,同一个问题在多个APP都类似的出现了,这里记录下这些常见的错误。

crash log:

java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{29b8ae38 V.E..... R.....I. 0,0-1160,607} not attached to window manager
        at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:370)
        at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:299)
        at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84)
        at android.app.Dialog.dismissDialog(Dialog.java:329)
        at android.app.Dialog.dismiss(Dialog.java:312)

设备信息:系统版本:4.4.2
根据错误log可以看出基本又是在Activity的生命周期上出现的问题,Activity已经销毁了,再调用Dialog.dismiss()方法。
经过代码排查,定位到了问题:

handler.postDelayed(dismissDialogRunnable,1000);

在Activity已经finish了,延迟1s后执行dismissDialogRunnable内对Dialog进行销毁。
知道问题了,就很好解决了,取消延迟,在Activity的OnDestory方法中销毁Dialog。
追根究底,下载了对应系统的的源码查看:
首先:Dialog.dismiss()方法:
这里写图片描述

在dismissDialog方法中调用了WindowManager的removeViewImmediate方法:

  @Override
    public void removeViewImmediate(View view) {
        mGlobal.removeView(view, true);
    }

mGlobal是WindowManagerGlobal实例对象,继续深入:

 public void removeView(View view, boolean immediate) {
        if (view == null) {
            throw new IllegalArgumentException("view must not be null");
        }

        synchronized (mLock) {
            int index = findViewLocked(view, true);
            View curView = mRoots.get(index).getView();
            removeViewLocked(index, immediate);
            if (curView == view) {
                return;
            }

            throw new IllegalStateException("Calling with view " + view
                    + " but the ViewAncestor is attached to " + curView);
        }
    }
    private int findViewLocked(View view, boolean required) {
        final int index = mViews.indexOf(view);
        if (required && index < 0) {
            throw new IllegalArgumentException("View=" + view + " not attached to window manager");
        }
        return index;
    }

在WindowManagerGlobal.findViewLocked中,会获取Dialog所在Window.decorView的位置,如果获取不到,则抛出异常。
至此,该问题发生的原因已经非常明了了。

其中部分内容参照:http://www.cnblogs.com/reverie/p/4846958.html

posted @ 2017-09-18 16:01  小小架构师  阅读(189)  评论(0编辑  收藏  举报