关于View的绘制流程的文章:
以下源码使用的是android源码4.0.4:
我们都清楚Activity中onCreate()方法在setContentView()后,View的宽高是获取不到的。同时我们知道Activity在onResume()后才完全可见,并且初次在onResume()方法中也是拿不到View的尺寸的,这样可以推算得出:View的绘制流程是在onResume()方法执行结束后才开始的。那Activity的生命周期方法背后是由谁,又何时调用的?
答:ActivityManagerService
ActivityManagerService(以下简称AMS))是Androids上层系统中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。
相对而言ActivityThread的main方法是应用程序的入口,main()方法里做一些初始化工作,其中包括和AMS建立起通信。
ActivityThread.java.main()
public static void main(String[] args) {
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
final H mH = new H();
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
//初始化lopper
Looper.prepareMainLooper();
//初始化ActivityThread
ActivityThread thread = new ActivityThread();
//ApplicationThread和AMS建立联系
thread.attach(false);
//取消息
// End of event ActivityThreadMain.
Trace.traceEnd(Trace Looper.loop();.TRACE_TAG_ACTIVITY_MANAGER);
//loop()方法如果执行结束,未能取到消息,程序抛出异常退出。
throw new RuntimeException("Main thread loop unexpectedly exited");
}
以下是 ActivityThread.java.attach(boolean system)
private void attach(boolean system) {
if (!system) {
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
...
mgr.attachApplication(mAppThread);
,,,
} catch (RemoteException ex) {
// Ignore
}
}
}
然后是ActivityManagerNative.java
private IBinder mRemote;
public void attachApplication(IApplicationThread app) throws RemoteException{
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {
switch (code) {
case ATTACH_APPLICATION_TRANSACTION: {
...
IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
...
return true;
}
}
}
ActivityThread会管理和用户打交道的Activity,应用所有的Activity都存在ActivityThread中的mActivities集合中,而ActivityThread响应AMS的号召,需要借助ApplicationThread来接受这个诏令,点进去看全都是生命周期方法。接着调用attach()方法让ApplicationThread和AMS建立联系。H类就是一个Handler类,用于发送生命周期改变的消息,通知响应操作。
private class ApplicationThread extends IApplicationThread.Stub {
//通知相应的进程执行启动Activity的操作
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public final void scheduleResumeActivity(IBinder token, int processState,
boolean isForward, Bundle resumeArgs) {
sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
}
//.....
}
当Activity启动时会先调用到scheduleLaunchActivity()方法,由Handler发送通知消息后执行handleLaunchActivity()->performLaunchActivity()->callActivityOnCreate()->Activity.onCreate()。
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
...
//该方法中会执行Activity的onCreate()方法。
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
...
} break;
//onResume();
case RESUME_ACTIVITY:
...
handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
args.argi3, "RESUME_ACTIVITY");
...
break;
}
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
Instrumentation mInstrumentation;
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
mInstrumentation.callActivityOnCreate(activity, r.state);
...
}
Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
...
activity.performCreate(icicle);
...
}
Activity.java
final void performCreate(Bundle icicle) {
onCreate(icicle);
...
}
protected void onCreate(Bundle savedInstanceState) {
...
}
然后是onResume()的方法:
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
//.............
//执行onResume()方法
r = performResumeActivity(token, clearHide, reason);
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;
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//将DecorView添加到Window上
wm.addView(decor, l);
}
}
//说法二:执行makeVisible()来添加View,但也是添加到Window里和上面一样的操作。清楚的小伙伴可以告诉我下。
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
}
onResume()时也一样,当Activity的状态发生改变,经过层层调用执行到handleResumeActivity()方法,在方法中先调用Activity.onResume()方法,再执行WindowManager的addView()方法将Activity的根View(DecorView)添加上去,进而开始绘制流程。这就解释了为什么初次在onResume()方法中获取不到View的宽高。对DecorView不太明白的可以参考 Activity中setContentView浅析。而WindowManager实现类为WindowManagerImpl,WindowManagerImpl中addView()方法如下。原文
WindowManagerImpl.java
ViewRootImpl root;
private void addView(View view, ViewGroup.LayoutParams params,CompatibilityInfoHolder cih, boolean nest) {
...
root.setView(view, wparams, panelParentView);
}
ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
requestLayout();
...
}
public void requestLayout() {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
requestLayout()方法走下去会异步执行performTraversals()方法,View的三大流程都是在该方法中执行的。到这儿我们算是明白View的绘制流程是从哪儿开始的,接下来分析这个过程到底是怎么做的。
public void scheduleTraversals() {
...
sendEmptyMessage(DO_TRAVERSAL);
...
}
case DO_TRAVERSAL:
performTraversals();
private void performTraversals() {
}