1.页面渲染时机
- 通过startActivity()进行Activity页面跳转时,会先调用onCreate方法,
- 在onCreate方法中通过调用setContentView()方法设置xml布局文件
- 在setContentView方法中通过调用LayoutInflate的inflate方法将xml布局文件的控件通过反射方式生成并以视图树(多叉树)的形式进行组织
- 问题1:为什么我们跳转到新的Activity页面就可以立刻看到布局文件设置的控件消息呢?系统在这一操作中做了哪些事情?
- Activity对象创建后,会以模版设计模式方式执行其生命周期方法,例如onCreate,onStart,onResume,其中onResume方法执行完后,用户才能与页面进行交互
- onResume方法的执行前,会先调用ActivityThread类的handleResumeActivity方法触发Activity页面的第一次渲染执行
- android.app.ActivityThread#handleResumeActivity
- 问题2:
- 当在滑动页面或者一个文本框的内容发生改变时,文件控件TextView可以调用setText()方法更新控件文本内容,setText()方法最后会调用View的requestLayout()方法进行渲染
2.ActivityThread的handleResumeActivity()方法
public final class ActivityThread extends ClientTransactionHandler {
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest,
boolean isForward,String reason) {
//1.调用Activity的onResume方法,并返回ActivityClientRecord对象r
final ActivityClientRecord r = performResumeActivity(token,
finalStateRequest, reason);
if (r == null) {
return;
}
//获取Activity对象a
final Activity a = r.activity;
final int forwardBit = isForward
? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
//表示当前Activity是否将要显示
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManager.getService().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
//获取activity的Window对象赋值给r的window变量
r.window = r.activity.getWindow();
//获取Activity中Window的根View(DecorView)
View decor = r.window.getDecorView();
//先将根View设置不可见
decor.setVisibility(View.INVISIBLE);
//获取ViewManager
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) {
//判断Activity之前是否添加过Window,默认为false,后面会赋值为true
//(保证只添加一次Window对象)
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//最后会调用WindowManager的addView()方法,将根View和Window的LayoutParams对象作为参数
wm.addView(decor, l);
} else {
//已经添加过Window,最后会调用View的requestLayout方法
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
r.hideForNow = true;
}
...
}
}
- 解析
- 在Activity的生命周期方法中,onCreare方法主要工作是调用setContentView方法,将xml布局文件中View控件通过反射常见View对象,并将所有控件组织为一颗视图树,这棵树的根节点为DecorView
- 其中DecorView是添加在PhoneWindow上的
- onResume生命周期方法调用完成后,页面才会真正显示在Window上,系统会调用handleResumeActivity方法进行处理,当Activity的mWindowAdded对象为false时,会调用WondowManger的addView()方法
2.2.其中Activiy中的mWindowManager变量是WindowManagerImpl实现类
- Activity的attach方法中初始化WindowManager对象
public class Activity extends ContextThemeWrapper... {
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
// 1.初始化Window对象,实现类为PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
//UI线程
mUiThread = Thread.currentThread();
...
//2.Window对象设置WindowManager对象
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
//获取WIndow的WindowManager对象,并赋值给mWindowManager变量
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
...
}
public WindowManager getWindowManager() {
return mWindowManager;
}
}
- Window的setWindowManager方法
- 调用WindowManagerImpl的createLocalWindowManager方法将Window作为参数进行WindowManager对象的初始化
public abstract class Window {
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
public WindowManager getWindowManager() {
return mWindowManager;
}
}
- WindowManagerImpl的createLocalWindowManager()方法
public final class WindowManagerImpl implements WindowManager {
//WindowManagerGlobal单例对象
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Context mContext;
private final Window mParentWindow;
private IBinder mDefaultToken;
public WindowManagerImpl(Context context) {
this(context, null);
}
private WindowManagerImpl(Context context, Window parentWindow) {
mContext = context;
mParentWindow = parentWindow;
}
//初始化
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);
}
//WindowManager的addView方法最后会调用WindowManagerGlobal的addView方法
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
}
- 解析:
- Activity初始化完成后,在生命周期方法调用前会先调用attach方法,会进行Window对象的初始化实现类是PhoneWindow
- 并给Window对象设置WindowManaer属性,WindowManager的实现类是WindowManagerImpl
- WindowManager的addView方法最终会调用WindowManagerGlobal的addView方法
3.WindowManagerGlobal的addView()方法
- 每次调用WindowManager的addView方法,都会在WindowManagerGlobal的addView方法中创建一个ViewRootImple对象
- 并最终调用ViewRootImpl的setView方法
public final class WindowManagerGlobal {
private final Object mLock = new Object();
private final ArrayList mViews = new ArrayList();
private final ArrayList mRoots = new ArrayList();
private final ArrayList mParams =
new ArrayList();
private final ArraySet mDyingViews = new ArraySet();
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
... // 校验操作
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// Start watching for system property changes.
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
// 判断当前添加的View是否已经添加过了
int index = findViewLocked(view, false);
if (index >= 0) {
//如果当前View之前调用过addView有过对应的ViewRootImpl对象,再次调用addView方法需要先
//删除之前添加到mRoots集合中的ViewRootImpl对象
//mDyingViews代表已经销毁过的View集合
if (mDyingViews.contains(view)) {
mRoots.get(index).doDie();
} else {
//mDyingViews没有包含,说明当前view已经添加过,不可能二次添加
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
}
...
//初始化ViewRootImpl对象root
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//添加到本地集合中
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
// 最后调用ViewRootImpl的setView方法
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
}
4.ViewRootImpl的setView方法
- ViewRootImpl的setView方法中会调用requestLayout方法,在该方法中不会立刻就执行view的渲染操作方法,而是先发送执行渲染操作的消息
- 在scheduleTraversals()方法中,先往当前消息队列MessageQueue中插入一条同步屏障消息
- 接着调用Choreographer的postCallback方法,发送异步消息,消息类型为CALLBACK_TRAVERSAL,并且设置了回调对象mTraversalRunnable
public final class ViewRootImpl implements ViewParent {
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
...
//核心,requestLayout方法
requestLayout();
...
//为View控制设置mParent为当前ViewRootImpl对象,后期如果view需要执行渲染时会调用mParent变量的requestLayout方法
view.assignParent(this);
...
//设置输入管道
CharSequence counterSuffix = attrs.getTitle();
mSyntheticInputStage = new SyntheticInputStage();
InputStage viewPostImeStage =
new ViewPostImeInputStage(mSyntheticInputStage);
...
}
}
}
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
//线程检查
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
//发送同步屏障消息
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 调用Choreographer的postCallback方法,发送异步消息,最后会调用mTraversalRunnable的回调方法
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
//移除同步屏障消息
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
performTraversals();
...
}
}
private void performTraversals() {
...
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, mWidth, mHeight);
...
performDraw();
}
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
if (mView == null) {
return;
}
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
}
}
}
4.2.Choreographer的postCallback方法
- Choreographer采用ThreadLocal实现单例对象,构造函数中初始化FrameHandler对象进行线程渲染切换,并初始化FrameDisplayEventReceiver进行vsync信号的请求和分发
- postCallback方法,会新增一个CallbackRecord节点,并保存到CallbackQueue队列中
- 然后调用DisplayEventReceiver.scheduleVsync()方法请求vsync信号,如果之前请求过vsync信号,mFrameScheduled的值设置为true,不会二次发起请求
public final class Choreographer {
private boolean mFrameScheduled; //重要变量,标示是否请求过执行渲染操作
//默认使用vsync
private static final boolean USE_VSYNC = SystemProperties.getBoolean(
"debug.choreographer.vsync", true);
private Choreographer(Looper looper, int vsyncSource) {
mLooper = looper;
//渲染使用的Handler,使渲染操作流程切换到主线程进行执行
mHandler = new FrameHandler(looper);
//初始化FrameDisplayEventReceiver,作用是接收与请求vsync信号
mDisplayEventReceiver = USE_VSYNC
? new FrameDisplayEventReceiver(looper, vsyncSource)
: null;
mLastFrameTimeNanos = Long.MIN_VALUE;
mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
//callback队列,使用数组组织起来
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
mCallbackQueues[i] = new CallbackQueue();
}
setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
}
private static final ThreadLocal sThreadInstance =
new ThreadLocal() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};
//通过ThreadLocal设置Chreographer的单例对象,ThreadLocal调用get方法会执行initialValue方法,对Chreographer对象进行初始化
public static Choreographer getInstance() {
return sThreadInstance.get();
}
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
...
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
//delayMillis为0;
//callbackType为类型Choreographer.CALLBACK_TRAVERSAL
//action为TraversalRunnable类型对象
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis; //now与dueTime相等
//获取渲染类型数组的队列,队列类型为CallbackRecord,采用链表结构组织
//忘队列中新增一个CallbackRecord节点,dueTime, action, token作为参数
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) { //默认不需要延迟
scheduleFrameLocked(now);
} else {
//如果有延迟时间,Handler发送MSG_DO_SCHEDULE_CALLBACK类型的异步消息
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
//该方法主要作用是请求vsync信号,最后会调用DisplayEventReceiver的scheduleVsync();方法执行native方法
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
//之前没有请求过执行渲染操作,则进入,并将mFrameScheduled置为true,保证执行一次,请求过再次调用不会进入
mFrameScheduled = true;
if (USE_VSYNC) {
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}
private boolean isRunningOnLooperThreadLocked() {
return Looper.myLooper() == mLooper;
}
}
5.VSYNC信号到达处理
- Choreographer类中又一个内部类FrameDisplayEventReceiver,它继承自DisplayEventReceiver,主要用于接收vsync信号
- 当vsync信号到来时会调用onVsync方法,通过Handler发送异步消息执行FrameDisplayEventReceiver的run方法
- 在run方法中接着执行doFrame方法,在doFrame方法中调用doCallbacks方法从不同类型的CallbackQueues队列中获取数据进行处理
- 从队列的头节点不断遍历,拿到CallbackRecord节点,执行内部设置的action的回调,其中就包含Choreographer.postCallback()方法调用设置的TraversalRunnable对象的run方法
private final class FrameDisplayEventReceiver extends DisplayEventReceiver
implements Runnable {
private boolean mHavePendingVsync;
private long mTimestampNanos;
private int mFrame;
public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
super(looper, vsyncSource);
}
//当vsync信号到来是调用
@Override
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
scheduleVsync();
return;
}
long now = System.nanoTime();
if (timestampNanos > now) {
timestampNanos = now;
}
if (mHavePendingVsync) {
} else {
mHavePendingVsync = true;
}
mTimestampNanos = timestampNanos;
mFrame = frame;
//通过Handler发送异步消息,消息封装时使用当前对象作为Handler的callback参数(FrameDisplayEventReceiver实现了Runnable接口)
//所以最后Handler会执行下面的run方法
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
@Override
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame);
}
//执行一帧画面的渲染
void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) { //没有请求vsync信号,说明队列中没有渲染消息,不作处理
return; // no work to do
}
long intendedFrameTimeNanos = frameTimeNanos;
startNanos = System.nanoTime();
final long jitterNanos = startNanos - frameTimeNanos;
if (jitterNanos >= mFrameIntervalNanos) {
final long skippedFrames = jitterNanos / mFrameIntervalNanos;
...//打印
frameTimeNanos = startNanos - lastFrameOffset;
}
if (frameTimeNanos < mLastFrameTimeNanos) {
scheduleVsyncLocked();
return;
}
if (mFPSDivisor > 1) {
long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos;
if (timeSinceVsync < (mFrameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) {
scheduleVsyncLocked();
return;
}
}
mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
mFrameScheduled = false;
mLastFrameTimeNanos = frameTimeNanos;
}
//调用doCallbacks方法从不同类型的CallbackQueues队列中获取设置的消息进行处理
try {
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
} finally {
AnimationUtils.unlockAnimationClock();
}
}
void doCallbacks(int callbackType, long frameTimeNanos) {
CallbackRecord callbacks;
synchronized (mLock) {
final long now = System.nanoTime();
//获取当前类型的CallbackQueues队列,获取头节点CallbackRecord对象
callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(
now / TimeUtils.NANOS_PER_MS);
if (callbacks == null) {
return;
}
mCallbacksRunning = true;
if (callbackType == Choreographer.CALLBACK_COMMIT) {
final long jitterNanos = now - frameTimeNanos;
if (jitterNanos >= 2 * mFrameIntervalNanos) {
final long lastFrameOffset = jitterNanos % mFrameIntervalNanos
+ mFrameIntervalNanos;
frameTimeNanos = now - lastFrameOffset;
mLastFrameTimeNanos = frameTimeNanos;
}
}
}
try {
//从队列头节点callbacks开始往后遍历,获取所有需要渲染的CallbackRecord,执行其中设置的action的run方法,或者doFrame方法
for (CallbackRecord c = callbacks; c != null; c = c.next) {
c.run(frameTimeNanos);
}
} finally {
//最后将队列中所有的节点数据进行重置
synchronized (mLock) {
mCallbacksRunning = false;
do {
final CallbackRecord next = callbacks.next;
recycleCallbackLocked(callbacks);
callbacks = next;
} while (callbacks != null);
}
}
}
private static final class CallbackRecord {
public CallbackRecord next;
public long dueTime;
public Object action; // Runnable or FrameCallback
public Object token;
public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
}
}
6.View的requestLayout方法
public class View implements Drawable.Callback, {
public void requestLayout() {
if (mMeasureCache != null) mMeasureCache.clear();
//ViewRootImpl正在执行渲染操作,直接return
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null && viewRoot.isInLayout()) {
if (!viewRoot.requestLayoutDuringLayout(this)) {
return;
}
}
mAttachInfo.mViewRequestingLayout = this;
}
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
//最后调用mParent的requestLayout(),mParent就是与View绑定的ViewRootImpl对象
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
mAttachInfo.mViewRequestingLayout = null;
}
}
void assignParent(ViewParent parent) {
if (mParent == null) {
mParent = parent;
} else if (parent == null) {
mParent = null;
} else {
throw new RuntimeException("view " + this + " being added, but"
+ " it already has a parent");
}
}
}
- 总结
- 当Activity调用onResume方法或者view控件调用requestLayout方法时都会执行渲染操作
- 其中在onResume方法中,会调用WindowManagerImpl的addView方法,将Activity的DecorView根view作为参数
- 然后调用WindowManagerGlobal的addView()方法,在该方法中会对应创建ViewRootImpl对象
- 最后调用ViewRootImpl的setView方法,接着调用scheduleTraversals方法
- scheduleTraversals方法中会想消息队列中插入同步屏障消息,并且调用Choreographer的postCallback方法发送异步消息
- 页面请求渲染操作并不会立刻执行渲染流程,而是会新增一个CALLBACK_TRAVERSAL类型的CallbackRecord对象,添加到队列中,并请求vsync信号
- 当接收vsync信号时,会调用FrameDisplayEventReceiver的onVsync方法,最后调用doFrame方法和doCallbacks方法,并从队列中取出所有插入的CallbackRecord对象,执行其中设置的action回调方法
- View的requestLayout方法最终会调用ViewRootImpl的scheduleTraversals方法,最后会回调mTraversalRunnable的run方法,之后执行ViewRootImpl的doTraversal方法
- doTraversal方法会执行控件的measure,layout,draw方法,从而完成视图树的测量,摆放和绘制流程