前文参考:
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 --
网友评论