注:本文解析的源码基于 API 25,部分内容来自于《Android开发艺术探索》。
第一篇:《Window源码解析(一):与DecorView的那些事》
第二篇:《Window源码解析(二):Window的添加机制》
第二篇:《Window源码解析(三):Window的更新机制》
Header
这篇将是 Window 系列的最后一篇了,主要来讲讲 Window 删除的机制原理。
其实相对于 Window 的添加和更新来说,删除也是换汤不换药的。也是通过 WindowSession 和 WindowManagerService 来完成这个步骤的。
Window的删除机制
我们删除 Window 的代码:
WindowManager.removeView
WindowManagerImpl
removeView(View view)
1 | @Override |
WindowManager 是一个接口,具体实现是 WindowManagerImpl 类。不用说,WindowManagerImpl 内部肯定是 WindowManagerGlobal 在“作祟”咯。
WindowManagerGlobal
removeView(View view, boolean immediate)
1 | public void removeView(View view, boolean immediate) { |
在 removeView(View view, boolean immediate)
先找到了打算删除的 View 的索引。然后根据索引去执行删除操作。
若 immediate
参数传入的是 true ,那么就执行了同步删除操作;否则就是异步删除操作了。大多使用的都是异步删除操作,避免出错,即 immediate
为 false;
其实这个方法的重点都放在了 removeViewLocked(index, immediate)
中了。
removeViewLocked(int index, boolean immediate)
1 | private void removeViewLocked(int index, boolean immediate) { |
在 removeViewLocked(int index, boolean immediate)
中,调用了 ViewRootImpl 的 die 方法。大多数的默认情况下,immediate
都为 false 。
之后又将 view 添加到 mDyingViews 中。mDyingViews 维持着都是即将要删除的 View 。
ViewRootImpl
die(boolean immediate)
1 | boolean die(boolean immediate) { |
在 die(boolean immediate)
方法中,不管同步还是异步,都是执行 doDie()
方法。不同的就是同步是马上执行,而异步是利用 Handler 去发消息,接收到消息后在执行。
doDie()
1 | void doDie() { |
doDie()
方法中主要看两点:
- dispatchDetachedFromWindow() 是去执行删除 window 的方法;
- WindowManagerGlobal.getInstance().doRemoveView(this) 把 mRoot 、mParams 和 mDyingViews 中关于当前 Window 的参数都移除了。
所以我们接下来,还是要看下 dispatchDetachedFromWindow() 方法。
1 | void dispatchDetachedFromWindow() { |
在方法一开头,先回调了 View 的 dispatchDetachedFromWindow 方法,该方法表示 View 马上要从 Window 上删除了。在这个方法内,可以做一些资源回收的工作。
之后做的就是一些垃圾回收的工作,比如清楚数据和消息,移除回调等。
再然后要看的就是 mWindowSession.remove(mWindow)
,这步才是真正调用了 Session 来移除 Window 的操作,是 IPC 的过程。具体的我们深入去看了。
Session
1 | public void remove(IWindow window) { |
在 Session 中直接调用了 WindowManagerService 的 removeWindow(Session session, IWindow client)
方法。
WindowManagerService
1 | public void removeWindow(Session session, IWindow client) { |
先得到 WindowState 对象,再调用 removeWindowLocked 去移除该 WindowState 。而具体的 removeWindowLocked 代码我们在这就不深入了,可以自行研究。
至此,整个 Window 移除机制就分析完毕了。
Footer
终于终于终于把 Window 的相关内容都重新梳理完毕了,也花了将近一个月的时间。
之前有一些似懂非懂的点也明朗了,但是还是有一些地方没有深入去涉及。比如 WindowManagerService 内部的操作。
以后的路还很长,期待自己再深入下去。