ViewRootImpl:负责view的布局 测量 绘制
DecorView:
因为oncreate走完,仅仅只是资源的准备工作,实际view的绘制工作是在onresume()中进行的,同时,这里要看ActivityThread的handlerMessage()方法中的RESUME_ACTIVITY,会走handleResumeActivity()方法中,performResumeActivity()方法得到一个ActivityRecord
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);//核心代码,l代表的是所有的资源和decorView添加到ViewManager
wm是一个接口,接口addView,实际就要找到它的一个实现类,也就是WindowManagerGlobal中的addView(),只是这里运用到了一个设计模式,直接分析WindowManagerGlobal的addView即可
核心代码
//前面一堆系统调用和资源配置就忽略掉了,主要是以下代码
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);//这三个add实际上是三个list
mRoots.add(root);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);//核心代码
ArrayList<View> mViews = new ArrayList<View>();
ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
ArrayList<WindowManager.LayoutParams> mParams =new ArrayList<WindowManager.LayoutParams>();
ViewRoot的setView()源码分析
内部主要有一个requestLayout() ==> scheduleTraversals()==> mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);==>实际上是调用了这个runable,而这个runable内部实际上是调用了doTraversal()方法
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
doTraversal中的核心方法是performTraversals();这里才正式开启了UI的绘制流程
WindowManage.LayoutParams,所有的资源都在这里
Rect frame 绘制了一个矩形。这个矩形并不是画布,而是意思大概就是,先确定他的整体位置
中间是一大堆比较恶心的计算。
下面,有一个测量方法performMeasure(),调用view的measure,再调用自身的onMeasure()方法
performLayout()布局==>view的layout(),再调用自身的onLayout();
performDraw()绘制==>view的draw(),再调用自身的onDraw();
draw中才会有surface画布,这个时候view才会显示出来
setContentView只是资源的准备
onresume才是真正的布局测量绘制
下一篇,对测量 布局 绘制流程的详细分析。