我们平时通过调用startActivity可以启动一个Activity,但是系统内部是如何启动这个Activity的?每个Activity也是一个对象,这个对象是啥时候被创建的(也就是说它的构造方法是什么时候被调用的)?为什么onCreate是Activity的执行入口?所有的这一切都被系统封装好了。
在分析之前,先介绍几个类:
Instrumentation类: startActivity方法的真正实现在Activity中的Instrumentation类对象,用来辅助Activity完成启动Activity的过程
activity中的定义: private Instrumentation mInstrumentation;
ActivityThread(包含ApplicationThread + ApplicationThreadNative + IApplicationThread):真正启动Activity的实现都在这里
activity中的定义: ActivityThread mMainThread
源码分析
首先看入口
code:Activity#startActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@Override
public
void
startActivity(Intent intent) {
startActivity(intent,
null
);
}
@Override
public
void
startActivity(Intent intent, Bundle options) {
if
(options !=
null
) {
startActivityForResult(intent, -
1
, options);
}
else
{
startActivityForResult(intent, -
1
);
}
}
public
void
startActivityForResult(Intent intent,
int
requestCode) {
startActivityForResult(intent, requestCode,
null
);
}
|
code:Activity#startActivityForResult
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
|
public
void
startActivityForResult(Intent intent,
int
requestCode, Bundle options) {
//一般的Activity其mParent为null,mParent常用在ActivityGroup中,ActivityGroup已废弃
if
(mParent ==
null
) {
//这里会启动新的Activity,核心功能都在mMainThread.getApplicationThread()中完成
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());
}
if
(requestCode >=
0
) {
mStartedActivity =
true
;
}
final
View decor = mWindow !=
null
? mWindow.peekDecorView() :
null
;
if
(decor !=
null
) {
decor.cancelPendingInputEvents();
}
// TODO Consider clearing/flushing other event sources and events for child windows.
}
else
{
//在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的
if
(options !=
null
) {
mParent.startActivityFromChild(
this
, intent, requestCode, options);
}
else
{
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(
this
, intent, requestCode);
}
}
}
|
code: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
25
26
27
28
29
30
31
32
|
public
ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent,
int
requestCode, Bundle options) {
//核心功能在这个whoThread中完成,其内部scheduleLaunchActivity方法用于完成activity的打开
IApplicationThread whoThread = (IApplicationThread) contextThread;
if
(mActivityMonitors !=
null
) {
synchronized
(mSync) {
//先查找一遍看是否存在这个activity
final
int
N = mActivityMonitors.size();
final ActivityMonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } }
}
}
try
{
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//这里才是真正打开activity的地方,核心功能在whoThread中完成。
int
result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target !=
null
? target.mEmbeddedID :
null
,
requestCode,
0
,
null
,
null
, options);
//这个方法是专门抛异常的,它会对启动activity的结果进行检查,如果无法打开activity,
//则抛出诸如ActivityNotFoundException类似的各种异常
checkStartActivityResult(result, intent);
}
catch
(RemoteException e) {
}
return
null
;
}</n;>
|
checkStartActivityResult,它也专业抛异常的,看代码,其中最熟悉的是Unable to find explicit activity class,如果你在xml中没有注册目标activity,此异常将会抛出。就是这个方法抛出来的。
static
void
checkStartActivityResult(
int
res, Object intent) {
if
(res >= ActivityManager.START_SUCCESS) {
return
;
}
switch
(res) {
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);
default
:
throw
new
AndroidRuntimeException(Unknown error code
+ res + when starting + intent);
}
}
接下来我们要去看看IApplicationThread,因为核心功能由其内部的scheduleLaunchActivity方法来完成,由于IApplicationThread是个接口,所以,我们需要找到它的实现类,它就是ActivityThread中的内部类ApplicationThread,看下它的继承关系:
private class ApplicationThread extends ApplicationThreadNative;
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread;
可以发现,ApplicationThread还是间接实现了IApplicationThread接口,先看下这个类的结构
看完ApplicationThread的大致结构,我们应该能够猜测到,Activity的生命周期中的resume、newIntent、pause、stop等事件都是由它触发的,事实上,的确是这样的。这里,我们为了说明问题,仅仅看scheduleLaunchActivity方法
code:ApplicationThread#scheduleLaunchActivity
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
|
public
final
void
scheduleLaunchActivity(Intent intent, IBinder token,
int
ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
int
procState, Bundle state, List<resultinfo> pendingResults,
List<intent> pendingNewIntents,
boolean
notResumed,
boolean
isForward,
String profileName, ParcelFileDescriptor profileFd,
boolean
autoStopProfiler) {
updateProcessState(procState,
false
);
//
ActivityClientRecord r =
new
ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}</intent></resultinfo>
|
说明:上述代码很好理解,构造一个activity记录,然后发送一个消息,所以,我们要看看Handler是如何处理这个消息的,现在转到这个Handler,它有个很短的名字叫做H
code:ActivityThread#H
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
|
//这个类太长,我只帖出了我们用到的部分
private
class
H
extends
Handler {
public
void
handleMessage(Message msg) {
if
(DEBUG_MESSAGES) Slog.v(TAG, >>> handling: + codeToString(msg.what));
switch
(msg.what) {
//这里处理LAUNCH_ACTIVITY消息类型
case
LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityStart);
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
//这里处理startActivity消息
handleLaunchActivity(r,
null
);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break
;
case
RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityRestart);
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break
;
case
PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityPause);
handlePauseActivity((IBinder)msg.obj,
false
, msg.arg1 !=
0
, msg.arg2);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break
;
...
}
}
|
说明:看来还要看handleLaunchActivity
code: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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
private
void
handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
if
(r.profileFd !=
null
) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(
null
,
null
);
if
(localLOGV) Slog.v(
TAG, Handling launch of + r);
//performLaunchActivity真正完成了activity的调起,
//同时activity会被实例化,并且onCreate会被调用
Activity a = performLaunchActivity(r, customIntent);
if
(a !=
null
) {
r.createdConfig =
new
Configuration(mConfiguration);
Bundle oldState = r.state;
//看到没,目标activity的onResume会被调用
handleResumeActivity(r.token,
false
, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if
(!r.activity.mFinished && r.startsNotResumed) {
try
{
r.activity.mCalled =
false
;
//同时,由于新activity被调起了,原activity的onPause会被调用
mInstrumentation.callActivityOnPause(r.activity);
if
(r.isPreHoneycomb()) {
r.state = oldState;
}
if
(!r.activity.mCalled) {
throw
new
SuperNotCalledException(
Activity + r.intent.getComponent().toShortString() +
did not call through to
super
.onPause());
}
}
catch
(SuperNotCalledException e) {
throw
e;
}
catch
(Exception e) {
if
(!mInstrumentation.onException(r.activity, e)) {
throw
new
RuntimeException(
Unable to pause activity
+ r.intent.getComponent().toShortString()
+ : + e.toString(), e);
}
}
r.paused =
true
;
}
}
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
);
}
catch
(RemoteException ex) {
// Ignore
}
}
}
|
说明:关于原activity和新activity之间的状态同步,如果大家感兴趣可以自己研究下,因为逻辑太复杂,我没法把所有问题都说清楚,否则就太深入细节而淹没了整体逻辑,研究源码要的就是清楚整体逻辑。下面看最后一个方法,这个方法是activity的启动过程的真正实现。
code:ActivityThread#performLaunchActivity
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
private
Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println(##### [ + System.currentTimeMillis() + ] ActivityThread.performLaunchActivity( + r + ));
ActivityInfo aInfo = r.activityInfo;
if
(r.packageInfo ==
null
) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//首先从intent中解析出目标activity的启动参数
ComponentName component = r.intent.getComponent();
if
(component ==
null
) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if
(r.activityInfo.targetActivity !=
null
) {
component =
new
ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity =
null
;
try
{
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//这里就是创建了一个activity的实例,用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象
//其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
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);
}
}
try
{
Application app = r.packageInfo.makeApplication(
false
, mInstrumentation);
if
(localLOGV) Slog.v(TAG, Performing launch of + r);
if
(localLOGV) Slog.v(
TAG, r + : app= + app
+ , appName= + app.getPackageName()
+ , pkg= + r.packageInfo.getPackageName()
+ , comp= + r.intent.getComponent().toShortString()
+ , dir= + r.packageInfo.getAppDir());
if
(activity !=
null
) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config =
new
Configuration(mCompatConfiguration);
if
(DEBUG_CONFIGURATION) Slog.v(TAG, Launching activity
+ r.activityInfo.name + with config + config);
activity.attach(appContext,
this
, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if
(customIntent !=
null
) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances =
null
;
activity.mStartedActivity =
false
;
int
theme = r.activityInfo.getThemeResource()
if
(theme !=
0
) {
activity.setTheme(theme);
}
activity.mCalled =
false
;
//目标activity的onCreate被调用了,到此为止,Activity被启动了,接下来的流程就是Activity的生命周期了,
//本文之前已经提到,其生命周期的各种状态的切换由ApplicationThread内部来完成
mInstrumentation.callActivityOnCreate(activity, r.state);
if
(!activity.mCalled) {
throw
new
SuperNotCalledException(
Activity + r.intent.getComponent().toShortString() +
did not call through to
super
.onCreate());
}
r.activity = activity;
r.stopped =
true
;
if
(!r.activity.mFinished) {
activity.performStart();
r.stopped =
false
;
}
if
(!r.activity.mFinished) {
if
(r.state !=
null
) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if
(!r.activity.mFinished) {
activity.mCalled =
false
;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
if
(!activity.mCalled) {
throw
new
SuperNotCalledException(
Activity + r.intent.getComponent().toShortString() +
did not call through to
super
.onPostCreate());
}
}
}
r.paused =
true
;
mActivities.put(r.token, r);
}
catch
(SuperNotCalledException e) {
throw
e;
}
catch
(Exception e) {
if
(!mInstrumentation.onException(activity, e)) {
throw
new
RuntimeException(
Unable to start activity + component
+ : + e.toString(), e);
}
}
return
activity;
}
|
Instrumentation类中newActivity方法的实现
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
可以看到系统创建activity实例也是通过类加载器反射调用的。
返回这个对象后,后面就调用这个对象的onCreate方法
动态加载中就是模拟了系统的这种行为来反射创建对象和启动onCreate方法.
但是只是模拟了这2步。和系统启动来说少了很多其他的初始化的工作。