美文网首页
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