Android笔记--View绘制流程源码分析二
通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中:
Window的建立(activit.attach生成),DecorView的建立(phonewindow.setContentView生成),
两者利用ViewRootImpl(WindowManagerGlobal.addView生成)建立window和decorview的联系。
并在root.setView(view, wparams, panelParentView)中把viewrootimpl(其本身也是一个viewparent)
作为参数传给decorview.从而让decorview一脉的所有view受viewRootImpl管理绘制。
在知道了上述Window DecorView WindowManager ViewRootImpl的来龙去脉以后就可以继续分析View
绘制的流程。
那么到底是谁触发了绘制呢?从源码中可以找到如下静态内部类:
static class W extends IWindow.Stub {
这个类就是负责处理来自系统进程的调用处理工作。在WMS中会触发相应的方法。而W中真正执行处理的
是ViewRootImpl。可以看一个其中的例子:
static class W extends IWindow.Stub {
。。。省略
@Override
public void dispatchAppVisibility(boolean visible) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchAppVisibility(visible);
}
}
。。。省略
}
W是在ViewRootImpl的构造函数中初始化的:
public ViewRootImpl(Context context, Display display) {
。。。省略
mWindow = new W(this);
}
所以这里的ViewRootImpl就是W中的ViewRootImpl对象。
从而系统进程远程触发绘制的流程:
viewAncestor.dispatchAppVisibility(visible);
这个就是ViewRootImpl的方法。最终会调用如下方法:
ViewRootImpl.java
public void dispatchAppVisibility(boolean visible) {
Message msg = mHandler.obtainMessage(MSG_DISPATCH_APP_VISIBILITY);
msg.arg1 = visible ? 1 : 0;
mHandler.sendMessage(msg);
}
//通过handler进行消息传递
void handleAppVisibility(boolean visible) {
if (mAppVisible != visible) {
mAppVisible = visible;
scheduleTraversals();
。。。省略
}
}
scheduleTraversals方法就是开始进行view绘制的入口方法
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
//这里的mTraversalRunnable就是一个runnable接口。其run方法内部是view绘制的全过程
。。。省略
}
}
void doTraversal() {
if (mTraversalScheduled) {
。。。省略
performTraversals();
。。。。省略
}
}
执行到此为止performTraversals方法就是众所周知的真 | View绘制流程!