Android Activity启动流程简要分析

我们启动一个Activity通常的做法就是:

1
startActivity(new Intent(MainActivity.this, xxx.class));

这是最简单的,那么这其中涉及到的过程是哪些的,新启动的Activity的对象是什么时候创建的,它的生命周期是怎么回调的?跟随本篇文章,我们将会对Activity的启动流程、生命周期的响应执行等常见现象有一个简要的认识。接下来就跟随源码分析的脚步,看看它的源码概要是怎样的。

首先从最简单的开始,进入到startActivity,

Activity#startActivity

1
2
3
4
5
6
7
8
9
10
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

我们进入到startActivity中会发现最终都会调用startActivityForResult方法,其实它跟我们直接调用startActivityForResult方法是一样的,我们进入到startActivityForResult方法中进行继续分析。

Activity#startActivityForResult

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//启动Activity,实现过程在Instrumentation中
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
//发送结果,即onActivityResult会被调用
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
//省略部分代码....
}

上面还没有进入到实现启动Activity的过程,我们继续跟进,

Instrumentation#execStartActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
//省略部分代码....
//真正启动Activity的过程是在这里面
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//校验打开Activity的结果,
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

其中有个方法checkStartActivityResult,这是检验执行startActivity的结果,里面有我们经常遇到的error。

Instrumentation#checkStartActivityResult

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/** @hide */
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
//常见错误,新建activity没有在AndroidManifest.xml中申明
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startVoiceActivity does not match active session");
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startAssistantActivity does not match active session");
case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start assistant activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}

我们看到IApplicationThread是一个接口,它的实现过程在ApplicationThread中,我们进入到ApplicationThread中去查看查看,ApplicationThread是定义在ActivityThread中的内部类,这里面就包含常见的一些方法,如:scheduleLaunchActivity,我们分析一下这个方法,

ActivityThread#ApplicationThread#scheduleLaunchActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
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) {
updateProcessState(procState, false);
//构造一个ActivityClientRecord然后发送消息
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
//...
//发送消息
sendMessage(H.LAUNCH_ACTIVITY, r);
}

在这里面首先构造一个ActivityClientRecord,然后发送消息到Handler进行处理,我们看看它的处理过程,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void handleMessage(Message msg) {
switch (msg.what) {
//启动一个Activity
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
//处理启动Activity
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
//省略其他处理,只看相关的...

我们接着进入到handleLaunchActivity中去,

ActivityThread#handleLaunchActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//省略无关代码...
//这里完成的新Activity的创建并被调用相关的onCreate、onStart方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
//省略无关代码...
//执行onResume生命周期
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
//省略无关代码...
}
//省略无关代码...
}
}

我们接着进入performLaunchActivity方法中查看Activity是如何被创建的。

ActivityThread#performLaunchActivity

由于performLaunchActivity方法太长,我们就不将代码贴出来了,有兴趣的话可以自己去跟踪查看,我们列出简要的重要的代码,

首先创建Activity,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Activity activity = null;
try {
//通过反射的方式,创建一个Activity对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}

用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象 ,其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。

Activity对象被创建出来后,那么它的生命周期也该得执行了,接着往下看,

1
2
3
4
5
6
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

上面代码就是调用Activity的onCreate生命周期,接着

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (!r.activity.mFinished) {
//onStart生命周期方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
//onRestoreInstanceState方法等根据相关条件判断是否需要执行
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}

以上就是Activity真正被创建并执行相关生命周期的过程,到这里基本上就是一个Activity被启动的简要过程。从创建一个Activity对象到执行它的生命周期方法,一步一步分析。我们追踪源码时应该记得不要深入细节,Android源码太庞大,如果深入细节的话,很容易会跳不出来,深陷其中。


关于作者:

1. 博客 http://crazyandcoder.github.io/

2. github https://github.com/crazyandcoder

3. 掘金 https://juejin.im/user/56b96af96240b8005865df59/share