上一篇博客传送门:一个Activity的显示过程总结(二)
上次我们追踪源码,分析到了ViewRoot这个关键的对象,接下来我们就从ViewRoot说起吧(ViewRoot貌似是android 2.x时候的说法了,现在变成了ViewRootImpl):
首先我们先来说明一下,ViewRoot是什么?
官方的注释如下:
The top of a view hierarchy, implementing the needed protocol between View and the WindowManager.
翻译为:View层次的顶端,实现View和WindowManager之间所需的协议。ViewRoot是由View组成的视图树状结构的“根”,但它并不处理绘画,而是处理有关于整个树状结构的事情(如遍历初始化、点击分发等)。
先来看看ViewRoot中的关键对象和构造函数:
(android.view.ViewRootImpl)
final IWindowSession mWindowSession; final W mWindow; View mView; // These can be accessed by any thread, must be protected with a lock. // Surface can never be reassigned or cleared (use Surface.clear()). private final Surface mSurface = new Surface(); public ViewRootImpl(Context context, Display display) { mContext = context; mWindowSession = WindowManagerGlobal.getWindowSession(); ... mWindow = new W(this); ... }
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { if (mView == null) { mView = view; ... // Schedule the first layout -before- adding to the window // manager, to make sure we do the relayout before receiving // any other events from the system. requestLayout(); ... } } }
public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true; scheduleTraversals(); } }
void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; mTraversalBarrier = mHandler.getLooper().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); scheduleConsumeBatchedInput(); } }
final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } } final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void doTraversal() { if (mTraversalScheduled) { ... try { performTraversals(); ... } }
private void performTraversals() { // cache mView since it is used so much below... final View host = mView; // DecorView ... // Ask host how big it wants to be performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); ... performLayout(lp, desiredWindowWidth, desiredWindowHeight); ... performDraw(); ... }