我们知道 View 的工作流程主要指测量 measure, 布局 layout, 绘制 draw 过程,但触发 View 去做这些操作的源头入口又在哪呢?之前有一篇写的是 setContentView,其实就是想找 View 工作流程的源头,但是没找到,我又回头看了书,发现这事还得从 startActivity 说起。
先说 startActivity
从 Activity 的 startActivity 开始,会先经过 Instrumentation,再经过 ActivityTaskManagerService(这里会通过 Binder 通信形式进行调用),再通过 ActivityStarter(这里转来转去很多层,要稍微耐心点看,最终走到 startActivityUnchecked() 方法),再经过 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked() 方法,转到 ActivityStack 的 resumeTopActivityUncheckedLocked() 方法,再又回到 ActivityStackSupervisor 转几转最终到 realStartActivityLocked()
接下来的逻辑不像以前,增加了一个事务的概念,ActivityManagerService 不再直接控制 Activity 的启动,而是通过 LifecycleManager 间接执行 ClientTransaction 来实现。总之就是大致逻辑框架不变,但中间增加了更丰富的细节控制。为了找这个入口,看了很久才算一知半解。另外在这过程中从 Android Studio 里看源码并不能看到全部,好在我通过这个 Android 系统源码 很方便的找到了我想看的部分。(注意要带上梯子)
//ClientTransaction 的 schedule
public void schedule() {
//这个 mClient 通过入参可以发现就是 app.thread,是 IApplicationThread 类型
//就是 ActivityThread 里的内部类 ApplicationThread
mClient.scheduleTransaction(this);
}
接下去回到 ActivityThread 的父类看看
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//ClientTransaction 的 preExecute()
public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
//这个 callbacks 是 add 进去的,代码里是添加了 LaunchActivityItem 类型的对象
if (mActivityCallbacks != null) {
final int size = mActivityCallbacks.size();
for (int i = 0; i < size; ++i) {
mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
}
}
//这个 request 是 set 进去的,代码里应该是设置了 ResumeActivityItem 类型的对象
if (mLifecycleStateRequest != null) {
mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
}
}
LaunchActivityItem 的 preExecute() 没做啥,大概做了些启动 Activity 的准备工作。接着 ResumeActivityItem 也做了 preExecute(),接下去是 ActivityThread.H, 处理 EXECUTE_TRANSACTION 消息。
{
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
//用事务处理器处理事务
mTransactionExecutor.execute(transaction);
break;
}
//TransactionExecutor
public void execute(ClientTransaction transaction) {
//关键的两句代码
//获取 transaction 的 callbacks 并遍历去挨个执行 callback 的 execute 和 postExecute
//前面说过 callbacks 里加了一个 LaunchActivityItem
executeCallbacks(transaction);
//获取 transaction 的 lifecycleStateRequest,然后去执行 request 的 execute 和 postExecute
executeLifecycleState(transaction);
}
重点的两句,来看下,
//LaunchActivityItem,只看 *execute* 就好,*postExecute* 可以不关心,重点不在它
public void execute(ClientTransactionHandler client, IIBinder token,
PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mIsForward,mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
//根据入参传递,这个 client 就是 ActivityThread
//调的这个方法不能再亲切了,接下去就是一顿操作猛如虎
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
//ResumeActivityItem 同样执行 execute 方法
public void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {
//熟悉不!熟悉不!熟悉不!这和 handleLaunchActivity 有着惊人的相似
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,"RESUME_ACTIVITY");
}
这样一来,接下去就是分析 handleLaunchActivity 和 handleResumeActivity 的事了。
再说 setContentView
handleLaunchActivity 里主要调了 performLaunchActivity,往下又调用了 activity 的 attach, Instrumentation 的 callActivityOnCreate 方法。callActivityOnCreate 方法又会调用 activity 的 performCreate,这个方法里面最终调用了我们熟悉的 onCreate 方法。后面的内容就可想而知了,调用了 setContentView 方法。
同样的,handleResumeActivity 里调用了 performResumeActivity,里面直接去调用了 activity 的 performResume,和 performCreate 不同,这里面首先会调用 performRestart,在里面会通过 Instrumentation 的 callActivityOnRestart 方法调用 activity 的 onRestart,而后又在里面调用了 performStart,通过 Instrumentation 的 callActivityOnStart 调用了 activity 的 onStart 方法。
再回到 performResume 里,继续往下会调用 Instrumentation 的 callActivityOnResume,也就调用了 activity 的 onResume 方法。
到这就解释了为啥 activity 的生命周期方法顺序是 onCreate->onRestart->onStart->onResume 了。
最后是 View 工作流程入口
回到 handleResumeActivity 里,继续往下 ViewManager 会将 activity 相关的 DecorView 添加进来。这个 ViewManager 是个接口,真正的实现类是 WindowManagerImpl,而最终做添加操作的实际是 WindowManagerGlobal 类对象。
继续 handleResumeActivity,添加完之后,最关键的一步操作是 ViewManager 要去刷新布局了,也就是调用了 updateViewLayout,显然最终的实现在 WindowManagerGlobal 里。
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
//这个 ViewRootImpl 对象是在上一步添加的时候创建的,里面有个 mView 变量,就是在添加的时候传进去的 DecorView 对象
ViewRootImpl root = mRoots.get(index);
//然后又到了关键的一步,设置布局参数
root.setLayoutParams(wparams, false);
}
最后在 ViewRootImpl 的 setLayoutParams 方法的最后调用了 scheduleTraversals(),这个可以说是 View 工作流程的入口。 更正一下,回看了那块代码,发现在 ViewRootImpl 对象添加 DecorView 的时候就已经开始要求 View 工作了,就是 setView() 方法,在方法里会调用 requestLayout() 来触发调用 scheduleTraversals() 方法。
完美!为了找这个入口,花了不少时间,主要是在 ActivityStarter 那里绕来绕去很久,后来静下心来慢慢分析还是被我找到了。