忽然有一天,我想要做一件事:去代码中去验证那些曾经被"灌输"的理论。
-- 服装学院的IT男
本篇已收录于Activity短暂的一生系列欢迎一起学习讨论Android应用开发或者WMS
V:WJB6995
Q:707409815
正文
生命周期系列:
本篇为"onCreate,onStart,onResume"的第二篇,介绍应用端 onCreate,onStart,onResume 的处理
1. onCreate
onCreate 是一个新 Activity 启动的第一个生命周期。而且根据前面的铺垫,也知道了他是在 onStart 和 onResume 执行的。
对应的事务为 LaunchActivityItem
# LaunchActivityItem
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// trace
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
// 应用段处理
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.countLaunchingActivities(-1);
}
完整的调用链如下:
LaunchActivityItem::execute
ActivityThread::handleLaunchActivity
ActivityThread::performLaunchActivity
Instrumentation::newActivity --- 创建Activity
Activity::attach --- 创建Window
Window::init
Window::setWindowManager
Instrumentation::callActivityOnCreate
Activity::performCreate
Activity::onCreate --- onCreate
ActivityClientRecord::setState --- 设置状态为 ON_CREATE(1)
这部分的代码其实在【Activity启动流程-3】的末尾有解释,单独拎出来再看一遍。
# ActivityThread
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
try {
// 重点* 1. 通过Instrumentation 反射创建Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
}
try {
......
// 重点* 2. 执行 attach 流程
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
重点* 3. OnCreate流程
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// 设置状态为 ON_CREATE(1)
r.setState(ON_CREATE);
} ......
......
}
# Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
// onCreate流程
activity.performCreate(icicle);
postPerformCreate(activity);
}
# Activity
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
// 执行onCreate
onCreate(icicle);
}
// wm_on_create_called
EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
"performCreate");
......
}
onCreate 的流程还是比较简单的,在 ActivityThread::performLaunchActivity 做了四件事:
-
- 反射创建 Activity 对象
-
- 执行 activity.attach,这里会创建Window
-
- 执行到 onCreate 生命周期
-
- 设置 ActivityClientRecord 中的状态为 ON_CREATE(1)
这里需要留意下会先执行 Activity::attach 来创建Window,然后才是后面的 Activity的onCreate。
创建 Window 的时候会创建 DecorView,有了这个 DecorView 我们在 onCreate 的时候才可以把对应的XML布局设置进去。
2. onStart
onStart 也有其对应的一个事务: StartActivityItem ,我一度以为启动 Activity 的时候也是通过这个事务来触发 onStart 的,但是实际情况我有点意外,它不是通过事务触发的,而是在执行 ResumeActivityItem 前,通过 TransactionExecutor::cycleToPath 触发的。
按下 recent 键再回到 Activity,这个时候onStart 是通过 StartActivityItem 触发的
当前分析 TransactionExecutor::cycleToPath 方法
# TransactionExecutor
// 工具类
private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
// 1. 获取当前ActivityClientRecord的生命周期状态值
final int start = r.getLifecycleState();
// log
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Cycle activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " from: " + getStateName(start) + " to: " + getStateName(finish)
+ " excludeLastState: " + excludeLastState);
}
// 2. 根据起始状态、结束状态以及是否排除最后一个状态,计算出生命周期状态变化的路径
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
// 3. 按照计算出的生命周期状态路径顺序执行相关操作
performLifecycleSequence(r, path, transaction);
}
-
- 获取到当前 Activity 的生命周期状态,目前是 ON_CREATE 也就是 1
-
- 通过工具类 计算出生命周期变化的路径,这个路径是啥呢, 比如说当前是 ON_CREATE(1),需要到 ON_RESUME(3), 那路径就是 [2]
-
- 根据第二步计算的路径开始执行各个生命周期
2.1 getLifecyclePath 计算生命周期切换路径
TransactionExecutor::getLifecyclePath 方法完整代码和解释都在下面了,但是我个人建议了解一下即可,大概浏览一下,留意我代码加了1,2,3 这3个重点的地方即可。
# TransactionExecutorHelper
// 定义需要经过的生命周期路径,长度为6(毕竟一共也才7个生命周期)
@ActivityLifecycleItem.LifecycleState
private IntArray mLifecycleSequence = new IntArray(6);
// start :开始的生命周期状态
// finish :结束的生命周期状态
// excludeLastState :是否移除最后一个状态
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
// 如果开始状态或结束状态未定义,则抛出异常
if (start == UNDEFINED || finish == UNDEFINED) {
throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
}
// 如果开始状态或结束状态是ON_RESTART,则抛出异常,因为在生命周期中不能以此状态开始或结束
if (start == ON_RESTART || finish == ON_RESTART) {
throw new IllegalArgumentException(
"Can't start or finish in intermittent RESTART state");
}
// 如果结束状态为PRE_ON_CREATE且开始状态不等于结束状态,则抛出异常,只能从预创建状态开始
if (finish == PRE_ON_CREATE && start != finish) {
throw new IllegalArgumentException("Can only start in pre-onCreate state");
}
// 重点* 1. 清空用于存储生命周期状态变更序列的集合
mLifecycleSequence.clear();
// 重点* 2. 分情况计算生命周期状态变更路径 (正常场景)
if (finish >= start) {
// 如果结束状态大于等于开始状态
if (start == ON_START && finish == ON_STOP) {
// 特殊情况:从开始到停止状态,无需经过暂停和恢复状态
mLifecycleSequence.add(ON_STOP);
} else {
// 重点* 3. 普通情况:直接将中间的所有状态加入序列 (正常场景)
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
} else { // 结束状态小于开始状态,不能简单地向下循环
if (start == ON_PAUSE && finish == ON_RESUME) {
// 特殊情况:从暂停直接到恢复状态
mLifecycleSequence.add(ON_RESUME);
} else if (start <= ON_STOP && finish >= ON_START) {
// 开始状态在ON_STOP之前且结束状态在ON_START之后的情况
// 先转为停止状态
for (int i = start + 1; i <= ON_STOP; i++) {
// 添加
mLifecycleSequence.add(i);
}
// 添加
mLifecycleSequence.add(ON_RESTART);
// 再转到指定结束状态
for (int i = ON_START; i <= finish; i++) {
mLifecycleSequence.add(i);
}
} else {
// 其他情况:需要重新启动并转到指定状态
// 先转到销毁状态
for (int i = start + 1; i <= ON_DESTROY; i++) {
// 添加
mLifecycleSequence.add(i);
}
// 再转到指定结束状态
for (int i = ON_CREATE; i <= finish; i++) {
// 添加
mLifecycleSequence.add(i);
}
}
}
// 如果要求排除最后一个状态并且生命周期序列不为空,则移除最后一个状态
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
// 返回计算好的生命周期状态变更序列
return mLifecycleSequence;
}
根据当前分析的场景,这个方法执行以下3步:
-
- 清除集合的数据,避免有脏数据影响结果
-
- 当前第一个参数是 ON_CREATE(1), 第二个参数定义在 ResumeActivityItem 下,返回值是 ON_RESUME(3),满足finish >= start的条件,所以进if语句
-
- 走 else 逻辑,最终 mLifecycleSequence 下也就一个元素 : 2 ,返回返回
2.2 performLifecycleSequence 切换Activity的生命周期
上一小节计算出需要执行的生命周期路径后,现在就要开始应用了。
# TransactionExecutor
// 实际执行在 ActiviThread
private ClientTransactionHandler mTransactionHandler;
// 构造方法赋值
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
mTransactionHandler = clientTransactionHandler;
}
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
// 当前场景就1个元素
final int size = path.size();
// 开始遍历
for (int i = 0, state; i < size; i++) {
// 获取到状态,当前就1个元素:ON_START( 2)
state = path.get(i);
// 打印log
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Transitioning activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " to state: " + getStateName(state));
}
switch (state) {
......
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions,
null /* activityOptions */);
break;
......
}
}
}
mTransactionHandler 在构造 TransactionExecutor 的构造方法赋值,创建对象的地方在 ActivityThread 中,传递的参数是 this,而 ActivityThread 是 ClientTransactionHandler 的子类,也就是说 mTransactionHandler 真正的实现还是在 ActivityThread。
# ActivityThread
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
// 拿到 Activity
final Activity activity = r.activity;
......
// Start
// 重点* 1. 执行onStart
activity.performStart("handleStartActivity");
// 2. 更新对应的状态
r.setState(ON_START);
......
// 重点* 3. 更新可见性,参数为true
updateVisibility(r, true /* show */);
mSomeActivitiesChanged = true;
......
}
一共处理了3件事,其中设置状态的逻辑之前看过了,看看另外2个重点流程。
2.3 onStart 流程
# Activity
final void performStart(String reason) {
......
// 执行onStart
mInstrumentation.callActivityOnStart(this);
// wm_on_start_called
EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason);
......
// Fragment 处理
mFragments.dispatchStart();
......
}
# Instrumentation
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
到这里 Activity 的 onStart 就执行了。
2.4 设置 View 可见
上一小节先执行到 onStart ,然后会设置 View 的可见性, 看一下具体代码
# ActivityThread
private void updateVisibility(ActivityClientRecord r, boolean show) {
// 拿到DecorView
View v = r.activity.mDecor;
if (v != null) {
if (show) {
if (!r.activity.mVisibleFromServer) {
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
// 设置 View 可见 (当前逻辑)
r.activity.makeVisible();
}
}
} else {
if (r.activity.mVisibleFromServer) {
r.activity.mVisibleFromServer = false;
mNumVisibleActivities--;
// 隐藏View
v.setVisibility(View.INVISIBLE);
}
}
}
}
当前是 onStart 逻辑,也看到了方法传递的参数是 true,说明要设置可见,所以会执行 Activity::makeVisible 逻辑。
# Activity
void makeVisible() {
if (!mWindowAdded) { // 之前setView时已置位true
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
// 设置可见
mDecor.setVisibility(View.VISIBLE);
}
2.5 onStart 小结
启动一个Activity 执行到 onStart 流程的分析就结束了,完整调用链如下:
TransactionExecutor::cycleToPath
TransactionExecutorHelper::getLifecyclePath
TransactionExecutor::performLifecycleSequence
ClientTransactionHandler::handleStartActivity
ActivityThread::handleStartActivity
Activity::performStart -- onStart
Instrumentation::callActivityOnStart
Activity::onStart
ActivityClientRecord::setState -- 状态设置为 ON_START
ActivityThread::updateVisibility -- 更新View可见性
Activity::makeVisible
View::setVisibility -- VISIBLE
如果是按多任务键(Recent)再回到 Activity 是会执行 ActivityRecord::makeActiveIfNeeded 来构建 StartActivityItem 事务处理 onStart 流程,但是后续的逻辑还是一样的
我们知道 onStart 和 onStop 是成对的, 那 onStart 会执行 View::setVisibility 设置 View 可见,那相对的在 onStop 流程是不是就会 设置 View 不可见呢?
这个疑问留到下一篇 onStop 流程解答。
当前还是继续看 onResume 的执行
3. onResume
onResume 对应事务为 ResumeActivityItem
# ResumeActivityItem
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
// Trace
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
// 应用端处理
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// TODO(lifecycler): Use interface callback instead of actual implementation.
ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
}
@Override
public int getTargetState() {
return ON_RESUME;
}
调用链如下:
ResumeActivityItem::execute
ActivityThread::handleResumeActivity
ActivityThread::performResumeActivity
Activity::performResume
Instrumentation::callActivityOnResume
Activity::onResume -- onResume
ActivityClientRecord::setState -- ON_RESUME
WindowManagerImpl::addView -- 创建ViewRootImpl
WindowManagerGlobal::addView
ViewRootImpl::setView -- 与WMS通信与WMS通信触发窗口的显示逻辑
开始撸代码。
# ActivityThread
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason) {
......
// 触发onResume
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
......
// 拿到activity
final Activity a = r.activity;
......
if (r.window == null && !a.mFinished && willBeVisible) {
// 将本地的window设置到activityRecord中
r.window = r.activity.getWindow();
// 获取DecorView
View decor = r.window.getDecorView();
// 设置不可见 在后面调用Activity::makeVisible会设为可见
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
// 获取参数
WindowManager.LayoutParams l = r.window.getAttributes();
// DecorView设置给Activity
a.mDecor = decor;
// 设置Activity的windowType,注意这个type,才是应用的窗口类型
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
......
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
// 重点:执行addView,并设置mWindowAdded=true
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
......
r.nextIdle = mNewActivities;
mNewActivities = r;
// stop 逻辑的触发
if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
当前分析 onResume 生命周期,所以只看 performResumeActivity 方法就好。
# ActivityThread
@VisibleForTesting
public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
String reason) {
// log
if (localLOGV) {
Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
}
......
// 触发 onResume
r.activity.performResume(r.startsNotResumed, reason);
// 设置状态
r.setState(ON_RESUME);
......
}
# Activity
final void performResume(boolean followedByPause, String reason) {
// trace
if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performResume:"
+ mComponent.getClassName());
}
......
// 主流程
mInstrumentation.callActivityOnResume(this);
// wm_on_resume_called
EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason);
......
// Fragments 处理
mFragments.dispatchResume();
......
}
流程和其他的一样,也是先通过 Instrumentation 然后又回到 Activity 处理,然后打印另一个 events 日志。
# Instrumentation
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
}
4. 总结
SourceActivity 在启动过程中会执行的3个生命周期已经分析完了,当前分析的场景下有以下几个点:
-
- 这3个生命周期的执行的连续的,
-
- onStart 原来这个场景下不是通过事务执行的
-
- 知道了 Activity 生命周期事务跨进程处理方式
-
- DecorView 的可见性是在 onStart 设置的
-
- 执行 onResume 的时候会触发窗口的添加显示,从严格意义上说,执行 onResume 的时候并不意味着手机屏幕上就有UI数据了。(但是不那么严谨思考的话,正常情况下,onResume 执行了差不多窗口也就显示了)
关于 events 日志的整理如下:
-
- wm_restart_activity 的触发在 ActivityTaskSupervisor::realStartActivityLocked 方法构建2个事务的时候,表示 SystemService 端要真正触发 TargetActivity 启动
-
- wm_on_create_called 的触发在 Activity::performCreate 方法,表示TargetActivity端执行 onCreate
-
- wm_on_start_called 的触发在 Activity::performStart 方法,表示TargetActivity端执行 onStart
-
- wm_on_resume_called 的触发在 Activity::performResume 方法,表示TargetActivity端执行 onResume