繪製入口:ActivityThread,我們先來看看ActivityThread中的handleMessage()方法。handleMessage()方法是由ActivityThread中一個名為H的繼承了Handler的子類中實現的。
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
......
handleLaunchActivity(r, null);
......
} break;
......
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}複製程式碼
在handleMessage方法中呼叫了handleLaunchActivity(r, null);啟動一個activity,我們再來看看handleLaunchActivity()方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
} else {
// If there was an error, for any reason, tell the activity
// manager to stop us.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}複製程式碼
在handleLaunchActivity方法中首先呼叫了performLaunchActivity()方法例項化activity物件。然後呼叫handleResumeActivity()方法。
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
......
// TODO Push resumeArgs into the activity for consideration
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
......
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l); //重點是addView方法
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r);
......
}
}複製程式碼
在handleResumeActivity()方法中會呼叫performResumeActivity()方法,performResumeActivity()方法中會回撥activity生命週期的onResume()方法。handleResumeActivity()中呼叫了 wm.addView(decor, l)方法,wm指的是WindowManagerImpl類。所有我們再來看看 WindowManagerImpl中的addView方法:
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mDisplay, mParentWindow);
}複製程式碼
在此方法中又呼叫了 mGlobal.addView(view, params, mDisplay, mParentWindow);mGlobal是WindowManagerGlobal。我們再去WindowManagerGlobal檢視addView方法:
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);
}
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// Don't wait for MSG_DIE to make it's way through root's queue.
mRoots.get(index).doDie();
} else {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
// The previous removeView() had not completed executing. Now it has.
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//新增到對應的集合中
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}複製程式碼
在此方法中例項化了一個名為root的ViewRootImpl物件。並呼叫了root.setView(view, wparams, panelParentView);我們再來看ViewRootImpl中的setView方法的實現:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
......
// 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();
......
}
}複製程式碼
我們可以看到在setView中呼叫了requestLayout()方法;在來看看requestLayout()方法的實現:
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread(); // 校驗繪製過程是否在主執行緒執行
mLayoutRequested = true;
scheduleTraversals();
}
}複製程式碼
在requestLayout()方法中又呼叫了scheduleTraversals()方法:
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
......
}
}複製程式碼
在scheduleTraversals方法中呼叫了mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null),這裡呼叫了mTraversalRunnable的執行緒。在這個執行緒中的run方法中呼叫了doTraversal()方法:
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}複製程式碼
doTraversal()方法中的實現如下:
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
if (mProfile) {
Debug.startMethodTracing("ViewAncestor");
}
performTraversals();
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
}
}
複製程式碼
doTraversal()方法中主要呼叫了perforTraversals()方法,在這個方法中呼叫了View的繪製流程的三大步:
private void performTraversals() {
performMeasure(); //測量 performLayout(); //佈局
performDraw(); //繪製}複製程式碼
總結:ActivityThread呼叫handleResumeActivity()方法,在handleResumeActivity()方法中呼叫WindowManagerImpl的addView()方法,進而呼叫WindowManagerGlobal中的addView()方法,在此方法中會建立ViewRootImpl物件,然後呼叫setView()方法將DecorView、佈局屬性物件關聯。關聯成功後呼叫會依次呼叫ViewRootImpl的requestLayout()-->scheduleTraversals()-->doTraversal()-->performTraversals();最終在performTraversals()方法中執行繪製流程三大步performMeasure()、performLayout()、performDraw()等方法。