美文网首页
Android Framework 之 Window / Win

Android Framework 之 Window / Win

作者: 行走中的3卡 | 来源:发表于2022-11-18 13:39 被阅读0次

前文参考:
Android Framework 之 Window / WindowManager基本概念及addView源码分析
Android Framework 之 Window / WindowManager (2) - updateViewLayout 源码分析

1. removeView源码分析

//WindowManagerGlobal.java

public final class WindowManagerGlobal {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    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);
        }
    }
}

分析:
(1) 与 updateViewLayout 逻辑类似
(2) 根据传入的view, 在mView 里找打 index
(3) 根据 index 找到对应的 ViewRootImpl 对象, 再获取到 对应的view对象
(4) 调用 removeViewLocked 继续执行 删除操作.

removeViewLocked 源码分析

    private void removeViewLocked(int index, boolean immediate) {
        ViewRootImpl root = mRoots.get(index);
        View view = root.getView();

        if (root != null) {
            root.getImeFocusController().onWindowDismissed();
        }
        boolean deferred = root.die(immediate);
        if (view != null) {
            view.assignParent(null);
            if (deferred) {
                mDyingViews.add(view);
            }
        }
    }

先获取到ViewRootImpl的 root 对象,然后调用root.die 执行

//ViewRootImpl
    boolean die(boolean immediate) {
        // Make sure we do execute immediately if we are in the middle of a traversal or the damage
        // done by dispatchDetachedFromWindow will cause havoc on return.
        if (immediate && !mIsInTraversal) {
            doDie();
            return false;
        }

        if (!mIsDrawing) {
            destroyHardwareRenderer();
        } else {
            Log.e(mTag, "Attempting to destroy the window while drawing!\n" +
                    "  window=" + this + ", title=" + mWindowAttributes.getTitle());
        }
        mHandler.sendEmptyMessage(MSG_DIE);
        return true;
    }

会调用 mHandler.sendEmptyMessage(MSG_DIE); 发送异步删除

   void doDie() {
        checkThread();
        if (LOCAL_LOGV) Log.v(mTag, "DIE in " + this + " of " + mSurface);
        synchronized (this) {
            if (mRemoved) {
                return;
            }
            mRemoved = true;
            if (mAdded) {
                dispatchDetachedFromWindow();
            }
           ....
            mAdded = false;
        }
        WindowManagerGlobal.getInstance().doRemoveView(this);
    }

真正执行删除的是在 dispatchDetachedFromWindow(), 如下代码所示

    void dispatchDetachedFromWindow() {
        ...
        mInsetsController.onWindowFocusLost();
        ....
        try {
            mWindowSession.remove(mWindow);
        } catch (RemoteException e) {
        ...
        unscheduleTraversals();
    }

mWindowSession 进行Binder 调用, 最后由WindowManagerService 执行.

参考文献:
http://aosp.opersys.com/xref/android-12.0.0_r2/
https://juejin.cn/post/7076274407416528909#heading-25

--- End --

相关文章

网友评论

      本文标题:Android Framework 之 Window / Win

      本文链接:https://www.haomeiwen.com/subject/nvrpxdtx.html