startActivity启动流程分析,Android 10

涉及的主要类

1.ActivityThreadApp的入口,进程中主线程的在main方法中执行。
2.ActivityTaskManager此类提供有关Activity及其任务栈(如任务,堆栈和显示)的信息,并与之交互。
3.ActivityTaskManagerService安卓10新增的类,主要负责activity的管理和调度工作,System service for managing activities and their containers (task, stacks, displays,... ).
4.ActivityManagerService继承自IActivityManager.Stub负责四大组件的、进程,生命周期与状态的切换。
5.ActivityStackSupervisor负责activity栈的管理,这个类的解释很有意思,估计谷歌下一步会改动这个类,看todo:

1
2
3
4
5
6
// TODO: This class has become a dumping ground. Let's
// - Move things relating to the hierarchy to RootWindowContainer
// - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler
// - Move interface things to ActivityTaskManagerService.
// - All other little things to other files.
--这个类过于繁重,考虑将与层次结构相关的事物移至RootWindowContainer,将与活动生命周期相关的事物移至新的名为ActivityLifeCycler的类,将接口事物移至ActivityTaskManagerService。将其他所有事物移至其他文件。

startActivity开始

1.当我们需要开启一个Activity的时候,通常都是通过调用startActivity(intent)方法。在Activity类中:

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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
startActivity(intent);   --->

@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);--->
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
//未传入Bundle-->options 走此方法
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1); --->
}
}

//文档中对requestCode的解释, requestCode If >= 0, this code will be returned inonActivityResult() when the activity exits.
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
//接上述方法,此处的requestCode = -1;< 0 ;
startActivityForResult(intent, requestCode, null);
} --->

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
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 = Activity
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}

startActivityFromChild的最终调用还是会走到
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}

startActivity最终的调用是在startActivityForResult,而根据activity是否存在实例,继而调用的是Instrumentation.execStartActivity。
mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, child,intent, requestCode, options);
此处的 mToken = IBinder 典型的IPC参数,猜测下一步会进行IPC通信。

(Instrumentation类中)
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//得到返回的是 IActivityTaskManager
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

(ActivityTaskManager类中)
/** @hide */
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
//AIDL IActivityTaskManager 的服务端即为 ActivityTaskManagerService
//public class ActivityTaskManagerService extends IActivityTaskManager.Stub {}
//由此转化到ActivityTaskManagerService
return IActivityTaskManager.Stub.asInterface(b);
}
};

ActivityTaskManagerService

1.上述最终调用到ActivityTaskManagerService.startActivity

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
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivityAsUser");

userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();

}
getActivityStartController得到ActivityStartController,而ActivityStartController.obtainStarter = ActivityStarter;
最终会调用ActivityStack.resumeTopActivityUncheckedLocked;

ActivityThread

上述所做的准备工作最终还是回到ActivityThread的方法handlePauseActivity,几个关键的方法handlePauseActivity–>performPauseActivity–>performPauseActivityIfNeeded。重点看这个方法:

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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}
// Always reporting top resumed position loss when pausing an activity. If necessary, it
// will be restored in performResumeActivity().
reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " 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 "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.setState(ON_PAUSE);
}
--->
@Override
public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
if (r != null) {
final boolean resumed = !r.paused;
if (!r.activity.mFinished && r.activity.mDecor != null
&& r.hideForNow && resumed) {
// We had hidden the activity because it started another
// one... we have gotten a result back and we are not
// paused, so make sure our window is visible.
updateVisibility(r, true);
}
if (resumed) {
try {
// Now we are idle.
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
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);
}
}
}
checkAndBlockForNetworkAccess();
deliverResults(r, results, reason);
if (resumed) {
r.activity.performResume(false, reason);
}
}
}
mInstrumentation.callActivityOnPause(r.activity);
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
--->
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;

if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}

// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);

if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);

// Initialize before creating the activity
if (!ThreadedRenderer.sRendererDisabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}
WindowManagerGlobal.initialize();

// Hint the GraphicsEnvironment that an activity is launching on the process.
GraphicsEnvironment.hintActivityLaunch();

final Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}

return a;
}
--->
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}

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);
}

ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
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);
}
}

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) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
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.configCallback,
r.assistToken);

if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}

activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
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.setState(ON_CREATE);

// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
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;
}

ActivityThread中的重要内部类‘H’

1.H:ActivityThread的一个继承Handler的内部类。activity的启动涉及到请求系统的服务,跨进程IPC通信,最终需要处理返回的请求信息。自然会想到Handler消息机制,当请求启动activity时,通过ActivityManagerService、ActivityTaskManagerService等一些系统的服务,包括进程的开启,activity状态信息的保存。任务栈信息,最后完成创建。

总结

Activity的启动流程,复杂且繁琐,代码很多,这里大概分析一部分流程,其中包括falgs等信息不在追究细节,做到大概心中有数;对关键方法了解。有其他需求时可对细节进一步细致查看。
1.开发者通过调用startActivity或者startActivityForResult最终调用startActivityForResult,以此向ActivityManagerService发送启动请求。
2.ActivityManagerService做一些初始化工作,包括启动模式,状态。10.0开始启动工作startActivityActivityTaskManagerService来完成。
3.判断当前栈顶是否有activity对象,如果有,则执行栈顶activity的onPause流程,(onPause–>源码的启动流程从侧面反应出,此方法不适合做太耗时的操作,为了新创建的activity启动更顺畅)。
4.当栈顶activity的onPause方法执行完成时,待启动的activity就绪,此时分为冷启动与热启动。若被启动过则执行的是:onRestart->onStart->onResume。冷启动则涉及到fork进程过程。首先对main线程初始化。
5.若被启动的activity主线程与进程已经初始化完成,这时主要对activity一些配置,包括主题,关联application等,onCreate->onStart->onResume
待执行完成,调用者activity会执行onStop方法,启动流程结束。

流程图:
JlaIVP.md.jpg
(图片来自网络,未找到10.0的流程图。。。)

这个功能是摆设,看看就好~~~