纪录一下Android 8.0版本应用启动的流程。
下面是桌面点击应用后,AMS的流程图。
相比Android 6.0,Android 8.0在添加了一个ActivityStarter类来处理Activity的启动。
对应上图,每个步骤的功能如下
1.ActivityManagerService.startActivityAsUser:添加上用户信息
2.ActivityStarter.startActivityMayWait:从pms获取要启动的Activity的在apk中的信息。
3.ActivityStarter.startActivityLocked,纪录启动的原因,启动的时间的一些变量中去。
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask, String reason) {
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
return mLastStartActivityResult;
}
4.ActivityStarter.startActivity,新建sourceRecord,callinguid,calling pid等。另外要对activity的进行权限检查。将要启动的Activity信息封装到ActivityRecord中。
5.ActivityStarter.startActivity,这个函数名跟步骤4是一样的,但传入的参数不一样。主要是defer延迟layout,等startActivityUnchecked完成之后,再继续continueSurfaceLayout。
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
mTargetStack);
return result;
}
6.ActivityStarter.startActivityUnchecked。这个函数主要是对要启动ActivityRecord进行处理,找到或者新建合适的Task,找到Stack,并把他们推到最前面或者Focus。
7.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked。这个函数是对Focused的stack的顶部Activity进行Resume的操作。
8.ActivityStack.resumeTopActivityInnerLocked。这个函数是Stack内部,对TopActivity进行Resume。
9.ActivityStackSupervisor.pauseBackStacks。暂停掉上个应用的Stack。例如如果应用从桌面启动,就是要暂停桌面。
问题思考
ActivityThread什么时候有了进程名?
在ActivityThread中,会调用attach方法,然后调用AMS的attachApplication
,让AMS跟应用进行绑定。AMS进而调用bindApplication,把应用的进程名告知给应用。应用在handleBindApplication调用Process.setArgV0设置进程名。
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain”);
…….
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
…….
throw new RuntimeException("Main thread loop unexpectedly exited");
}
OnRume时,界面显示完成了吗?
没有。
可以看到下面,先调用performResumeActivity,再调用addView。啧啧!!!
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
..........
ActivityClientRecord r = performResumeActivity(token, clearHide);
.......
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
ActivityThread中有多少个handle函数
他妹的,还挺多的。
handleActivityConfigurationChanged
handleBindApplication
handleBindService
handleCancelVisibleBehind
handleConfigurationChanged
handleCreateBackupAgent
handleCreateService
handleDestroyActivity
handleDestroyBackupAgent
handleDispatchPackageBroadcast
handleDumpActivity
handleDumpHeap
handleDumpProvider
handleDumpService
handleEnterAnimationComplete
handleInstallProvider
handleLaunchActivity
handleLowMemory
handleMessage
handleNewIntent
handleOnBackgroundVisibleBehindChanged
handlePauseActivity
handleProfilerControl
handleReceiver
handleRelaunchActivity
handleRequestAssistContextExtras
handleResumeActivity
handleSendResult
handleServiceArgs
handleSetCoreSettings
handleSleeping
handleStopActivity
handleStopService
handleTranslucentConversionComplete
handleTrimMemory
handleUnbindService
handleUnstableProviderDied
handleUnstableProviderDiedLocked
handleBindApplication和handleLaunchActivity的调用关系?
肯定时先handleBindApplication,再调用handleLaunchActivity。
handleBindApplication时应用启动的时候调用的。handleLaunchActivity时应用启动Activity时候用的,会调用Activity的oncreate,onstart函数。
跟Activity生命周期搞一起的还有handleResumeActivity,handlePauseActivity,handleStopActivity,handleDestroyActivity!!