1 前言
我们在上一章节【Android Framework系列】第5章 AMS启动流程中简单的分析了AMS的启动流程
,这一章节我们来了解一下,通过AMS
是怎么完成Activity的启动
下面我们通过Launcher启动
一起来看看Activity的启动流程
本文基于Android10(Q)的源码做分析
2 Launcher启动流程
2.1 SystemServer启动AMS,准备启动Launcher
由【Android Framework系列】第5章 AMS启动流程我们可以知道:
- 手机开机后会启动
system_server进程
,然后调用SystemServer
的main()
方法, - 在
main()
方法中通过startBootstrapServices()
启动AMS。 - 之后通过
startOtherServices()
方法调用AMS
的systemReady()
,告知AMS
可以执行第三方代码。 systemReady()
方法中,通过调用startHomeOnAllDisplays()
来启动初始Activity。
2.2 进程启动与Activity启动前奏
2.2.1 ActivityManagerService的startHomeOnAllDisplays()
我们就从startHomeOnAllDisplays()
方法开始继续分析:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
8967
8968 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
......
// 调用ActivityTaskManagerService的startHomeOnAllDisplays方法(就是启动Launcher的Activity)
9084 mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
......
9144 }
这里mAtmInternal
为ActivityTaskManagerService
对象,而startHomeOnAllDisplays()
方法直接调用的是RootActivityContainer
对象的该同名方法。
2.2.2 ActivityTaskManagerService的startHomeOnAllDisplays()
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
6691 @Override
6692 public boolean startHomeOnAllDisplays(int userId, String reason) {
6693 synchronized (mGlobalLock) {
// 此处会调用mRootWindowContainer对象的startHomeOnAllDisplays函数
// 这边的mRootWindowContainer参数的值是从WindowManagerService中的mRoot参数对应的对象
// mRootWindowContainer参数是通过AMS的setWindowManager函数调用,进而调用ATMS.LocalServices的setWindowManager函数得到的
// 因此,此处需要注意的是RootWindowContainer对象的mWmService参数对应的是WindowManagerService对象
// mService参数对应的是ActivityTaskManagerService对象
6694 return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
6695 }
6696 }
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
332 boolean startHomeOnAllDisplays(int userId, String reason) {
333 boolean homeStarted = false;
// getChildCount获取显示设备数目,这个主要从mChildren参数中获取对应的数量
// mChildren是一个WindowList的一个对象,其包含的数据是在setWindowManager函数被调用时,
// 从DisplayManagerService中获取到的Display的数目,
334 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
// 获取到对应新建的DisplayContent的displayId
335 final int displayId = mActivityDisplays.get(i).mDisplayId;
// 调用startHomeOnDisplay函数
336 homeStarted |= startHomeOnDisplay(userId, reason, displayId);
337 }
338 return homeStarted;
339 }
......
366 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
367 boolean fromHomeKey) {
368 // Fallback to top focused display if the displayId is invalid.
// 由于DisplayManagerService中获取到的displayId不为INVALID_DISPLAY,因此此处判断条件不满足
// 如果displayId无效,则退回到顶层拥有焦点的显示设备
369 if (displayId == INVALID_DISPLAY) {
370 displayId = getTopDisplayFocusedStack().mDisplayId;
371 }
372
373 Intent homeIntent = null;
374 ActivityInfo aInfo = null;
375 if (displayId == DEFAULT_DISPLAY) {
// 获取Lancher的第一个页面的intent,其category为Intent.CATEGORY_HOME
376 homeIntent = mService.getHomeIntent();
// 通过intent找到Launcher中AndroidManifest对应的activity标签,解析出相应的activityInfo和applicationInfo信息
377 aInfo = resolveHomeActivity(userId, homeIntent);
378 } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
// 多屏显示功能,可以参考官网说明
// https://source.android.google.cn/devices/tech/display/multi_display/system-decorations#launcher
379 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
380 aInfo = info.first;
381 homeIntent = info.second;
382 }
383 if (aInfo == null || homeIntent == null) {
384 return false;
385 }
386
387 if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
388 return false;
389 }
390
// 在启动前,校验是否满足启动条件,大概校验了displayId的有效性、对应activity的启动模式、是否处于工厂测试模式等等
392 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
393 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// 传入的fromHomeKey的值为false
395 if (fromHomeKey) {
396 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
397 }
398 // Update the reason for ANR debugging to verify if the user activity is the one that
399 // actually launched.
400 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
401 aInfo.applicationInfo.uid) + ":" + displayId;
// 转到ActivityStartController类中继续调用startHomeActivity方法
402 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
403 displayId);
404 return true;
405 }
......
412 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
413 final int flags = ActivityManagerService.STOCK_PM_FLAGS;
414 final ComponentName comp = homeIntent.getComponent();
415 ActivityInfo aInfo = null;
416 try {
417 if (comp != null) {
418 // Factory test.
419 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
420 } else {
421 final String resolvedType =
422 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
423 final ResolveInfo info = AppGlobals.getPackageManager()
424 .resolveIntent(homeIntent, resolvedType, flags, userId);
425 if (info != null) {
426 aInfo = info.activityInfo;
427 }
428 }
429 } catch (RemoteException e) {
430 // ignore
431 }
432
433 if (aInfo == null) {
434 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
435 return null;
436 }
437
438 aInfo = new ActivityInfo(aInfo);
439 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
440 return aInfo;
441 }
从上述这段代码可以看到,这边主要是依次做了四件事情
RootActivityContainer
类中,此处会针对于多显示设备的情况,启动多个Launcher
主界面,当然在这边,我们只分析默认显示设备的情况。- 通过
ATMS
的getHomeIntent
函数,获取启动Activity
的一个Intent
对象 resolveHomeActivity
函数通过PMS
获取启动界面的ActivityInfo
对象- 通过
ActivityStartController
对象的startHomeActivity
函数来启动对应的Activity
2.2.3 ActivityStartController的startHomeActivity()
我们继续看看ActivityStartController
里的startHomeActivity()
方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
......
171 void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
// 创建一个ActivityOptions的对象
172 final ActivityOptions options = ActivityOptions.makeBasic();
// FULLSCREEN模式启动Activity
173 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
174 if (!ActivityRecord.isResolverActivity(aInfo.name)) {
// 判断当前是否拥有多个Launcher并处于选择Launcher状态,否的话设置ACTIVITY_TYPE_HOME属性,直接启动Launcher的Activity
178 options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
179 }
180 options.setLaunchDisplayId(displayId);
// 执行启动任务
181 mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
182 .setOutActivity(tmpOutRecord)
183 .setCallingUid(0)
184 .setActivityInfo(aInfo)
185 .setActivityOptions(options.toBundle())
186 .execute();
187 mLastHomeActivityStartRecord = tmpOutRecord[0];
188 final ActivityDisplay display =
189 mService.mRootActivityContainer.getActivityDisplay(displayId);
190 final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
191 if (homeStack != null && homeStack.mInResumeTopActivity) {
192 // If we are in resume section already, home activity will be initialized, but not
193 // resumed (to avoid recursive resume) and will stay that way until something pokes it
194 // again. We need to schedule another resume.
195 mSupervisor.scheduleResumeTopActivities();
196 }
197 }
......
执行开始任务,obtainStarter()
方法内从缓存池内获取ActivityStarter
对象(没有则创建一个),通过execute()
方法执行Activity的启动
2.2.4 ActivityStarter的execute()
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
......
509 int execute() {
510 try {
511 // TODO(b/64750076): Look into passing request directly to these methods to allow
512 // for transactional diffs and preprocessing.
513 if (mRequest.mayWait) {
514 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
515 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
516 mRequest.intent, mRequest.resolvedType,
517 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
518 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
519 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
520 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
521 mRequest.inTask, mRequest.reason,
522 mRequest.allowPendingRemoteAnimationRegistryLookup,
523 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
524 } else {
525 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
526 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
527 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
528 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
529 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
530 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
531 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
532 mRequest.outActivity, mRequest.inTask, mRequest.reason,
533 mRequest.allowPendingRemoteAnimationRegistryLookup,
534 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
535 }
536 } finally {
537 onExecutionComplete();
538 }
539 }
......
mRequest.mayWait
在执行execute()
前没有赋值,默认false,我们继续看startActivity()
方法:
2.2.5 ActivityStarter的startActivity()
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
......
611 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
612 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
613 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
614 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
615 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
616 SafeActivityOptions options,
617 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
618 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
619 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
......
// 创建被启动的Activity对应的ActivityRecord对象
899 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
900 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
901 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
902 mSupervisor, checkedOptions, sourceRecord);
903 if (outActivity != null) {
904 outActivity[0] = r;
905 }
906
907 if (r.appTimeTracker == null && sourceRecord != null) {
908 // If the caller didn't specify an explicit time tracker, we want to continue
909 // tracking under any it has.
910 r.appTimeTracker = sourceRecord.appTimeTracker;
911 }
912
913 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
// 如果我们启动的activity与当前恢复的activity的uid不同,请检查是否允许应用程序切换。
917 if (voiceSession == null && (stack.getResumedActivity() == null
918 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
919 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
920 realCallingPid, realCallingUid, "Activity start")) {
921 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
922 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
923 sourceRecord, startFlags, stack, callerApp));
924 }
925 ActivityOptions.abort(checkedOptions);
926 return ActivityManager.START_SWITCHES_CANCELED;
927 }
928 }
929
930 mService.onStartActivitySetDidAppSwitch();
931 mController.doPendingActivityLaunches(false);
932
933 final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
934 true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
935 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
936 return res;
937 }
......
1386 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1387 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1388 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1389 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
1390 int result = START_CANCELED;
1391 final ActivityStack startedActivityStack;
1392 try {
1393 mService.mWindowManager.deferSurfaceLayout();
1394 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1395 startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
1396 } finally {
......
1431 }
1432
1433 postStartActivityProcessing(r, result, startedActivityStack);
1434
1435 return result;
1436 }
......
// Note: This method should only be called from {@link startActivity}.
1464 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1465 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1466 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1467 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
......
// 如果正在启动的activity与当前在顶部的activity相同,那么我们需要检查它是否应该只启动一次
1625 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
1626 final ActivityRecord topFocused = topStack.getTopActivity();
1627 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1628 final boolean dontStart = top != null && mStartActivity.resultTo == null
1629 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1630 && top.mUserId == mStartActivity.mUserId
1631 && top.attachedToProcess()
1632 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1633 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1634 // This allows home activity to automatically launch on secondary display when
1635 // display added, if home was the top activity on default display, instead of
1636 // sending new intent to the home activity on default display.
1637 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
1638 if (dontStart) {
1639 // For paranoia, make sure we have correctly resumed the top activity.
1640 topStack.mLastPausedActivity = null;
1641 if (mDoResume) {
1642 mRootActivityContainer.resumeFocusedStacksTopActivities();
1643 }
1644 ActivityOptions.abort(mOptions);
1645 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1646 // We don't need to start a new activity, and the client said not to do
1647 // anything if that is the case, so this is it!
1648 return START_RETURN_INTENT_TO_CALLER;
1649 }
1650
1651 deliverNewIntent(top);
1652
1653 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1654 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1655 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
1656 mPreferredDisplayId, topStack);
1657
1658 return START_DELIVERED_TO_TOP;
1659 }
......
// 往ActivityStack中写入启动的activity记录,同时更新TaskRecord信息
1700 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1701 mOptions);
1702 if (mDoResume) {
1703 final ActivityRecord topTaskActivity =
1704 mStartActivity.getTaskRecord().topRunningActivityLocked();
1705 if (!mTargetStack.isFocusable()
1706 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1707 && mStartActivity != topTaskActivity)) {
// 如果activity无焦点的,我们不能恢复它,但仍然希望确保它在启动时时变得可见(这也将触发入场动画)。
// 此外,我们不希望在当前有覆盖层的Task中恢复activity,
// 因为正在启动的activity只需要处于可见的暂停状态,直到覆盖层被移除。
1714 mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
1715 // Go ahead and tell window manager to execute app transition for this activity
1716 // since the app transition will not be triggered through the resume channel.
1717 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
1718 } else {
1719 // If the target stack was not previously focusable (previous top running activity
1720 // on that stack was not visible) then any prior calls to move the stack to the
1721 // will not update the focused stack. If starting the new activity now allows the
1722 // task stack to be focusable, then ensure that we now update the focused stack
1723 // accordingly.
1724 if (mTargetStack.isFocusable()
1725 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
1726 mTargetStack.moveToFront("startActivityUnchecked");
1727 }
1728 mRootActivityContainer.resumeFocusedStacksTopActivities(
1729 mTargetStack, mStartActivity, mOptions);
1730 }
1731 } else if (mStartActivity != null) {
1732 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
1733 }
1734 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
1735
1736 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1737 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
1738
1739 return START_SUCCESS;
1740 }
1741
......
它调用了RootActivityContainer
的resumeFocusedStacksTopActivities()
方法,启动目标ActivityStack
的最顶层activity
。我们继续看RootActivityContainer类的resumeFocusedStacksTopActivities()
:
2.2.6 RootActivityContainer的resumeFocusedStacksTopActivities()
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
1148 boolean resumeFocusedStacksTopActivities(
1149 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
......
1156 if (targetStack != null && (targetStack.isTopStackOnDisplay()
1157 || getTopDisplayFocusedStack() == targetStack)) {
1158 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1159 }
1160
1161 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
......
1185 if (!resumedOnDisplay) {
1186 // In cases when there are no valid activities (e.g. device just booted or launcher
1187 // crashed) it's possible that nothing was resumed on a display. Requesting resume
1188 // of top activity in focused stack explicitly will make sure that at least home
1189 // activity is started and resumed, and no recursion occurs.
1190 final ActivityStack focusedStack = display.getFocusedStack();
1191 if (focusedStack != null) {
1192 focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
1193 }
1194 }
1195 }
1196
1197 return result;
1198 }
我们接着往下追踪,它调用了ActivityStack
的resumeTopActivityInnerLocked()
方法。
2.2.7 ActivityStack的resumeTopActivityUncheckedLocked()
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
2565 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
......
2572 try {
2573 // Protect against recursion.
2574 mInResumeTopActivity = true;
2575 result = resumeTopActivityInnerLocked(prev, options);
......
2588 } finally {
2589 mInResumeTopActivity = false;
2590 }
2591
2592 return result;
2593 }
......
2613 @GuardedBy("mService")
2614 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
// 暂停上一个activity
2744 boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
2745 if (mResumedActivity != null) {
2746 if (DEBUG_STATES) Slog.d(TAG_STATES,
2747 "resumeTopActivityLocked: Pausing " + mResumedActivity);
2748 pausing |= startPausingLocked(userLeaving, false, next, false);
2749 }
// 如果最近的activity没有历史记录,但由于设备进入睡眠状态而被停止,而不是停止+销毁,我们需要确保销毁它,因为我们正在使一个新的activity处于最顶层。
2781 if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
2782 !mLastNoHistoryActivity.finishing) {
2783 if (DEBUG_STATES) Slog.d(TAG_STATES,
2784 "no-history finish of " + mLastNoHistoryActivity + " on new resume");
2785 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
2786 null, "resume-no-history", false);
2787 mLastNoHistoryActivity = null;
2788 }
2789
2790 if (prev != null && prev != next && next.nowVisible) {
// 下一个activity已经可见,所以现在隐藏前一个activity的窗口,以便我们可以尽快显示新的activity。
// 我们只有在前一个结束时才这样做,这意味着它在resume的那个之上,所以快速隐藏它是有好处的。
// 否则,我们希望按照正常的方式显示resume的activity,
// 这样我们就可以根据新activity是否全屏来决定是否应该隐藏以前的activity
2800 if (prev.finishing) {
2801 prev.setVisibility(false);
2802 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2803 "Not waiting for visible to hide: " + prev
2804 + ", nowVisible=" + next.nowVisible);
2805 } else {
2806 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2807 "Previous already visible but still waiting to hide: " + prev
2808 + ", nowVisible=" + next.nowVisible);
2809 }
2810
2811 }
2812
2813 // Launching this app's activity, make sure the app is no longer
2814 // considered stopped.
2815 try {
2816 AppGlobals.getPackageManager().setPackageStoppedState(
2817 next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
2818 } catch (RemoteException e1) {
2819 } catch (IllegalArgumentException e) {
2820 Slog.w(TAG, "Failed trying to unstop package "
2821 + next.packageName + ": " + e);
2822 }
// 我们正在启动下一个activity,所以告诉window manager,
// 上一个activity很快就会被隐藏。这样,它可以知道在计算所需的屏幕方向时忽略它。
2827 boolean anim = true;
2828 final DisplayContent dc = getDisplay().mDisplayContent;
2829 if (prev != null) {
2830 if (prev.finishing) {
2831 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2832 "Prepare close transition: prev=" + prev);
2833 if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
2834 anim = false;
2835 dc.prepareAppTransition(TRANSIT_NONE, false);
2836 } else {
2837 dc.prepareAppTransition(
2838 prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_CLOSE
2839 : TRANSIT_TASK_CLOSE, false);
2840 }
2841 prev.setVisibility(false);
2842 } else {
2843 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2844 "Prepare open transition: prev=" + prev);
2845 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2846 anim = false;
2847 dc.prepareAppTransition(TRANSIT_NONE, false);
2848 } else {
2849 dc.prepareAppTransition(
2850 prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_OPEN
2851 : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
2852 : TRANSIT_TASK_OPEN, false);
2853 }
2854 }
2855 } else {
2856 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
2857 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2858 anim = false;
2859 dc.prepareAppTransition(TRANSIT_NONE, false);
2860 } else {
2861 dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
2862 }
2863 }
2864
2865 if (anim) {
2866 next.applyOptionsLocked();
2867 } else {
2868 next.clearOptionsLocked();
2869 }
2870
2871 mStackSupervisor.mNoAnimActivities.clear();
2872
2873 if (next.attachedToProcess()) {
// 只有启动过的activity才会进入此分支
......
3025 } else {
3026 // Whoops, need to restart this activity!
3027 if (!next.hasBeenLaunched) {
3028 next.hasBeenLaunched = true;
3029 } else {
3030 if (SHOW_APP_STARTING_PREVIEW) {
// 冷启动的过渡页,在这里会载入manifest配置的主题背景,
// 如果没有的话,默认白屏或黑屏
3031 next.showStartingWindow(null /* prev */, false /* newTask */,
3032 false /* taskSwich */);
3033 }
3034 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
3035 }
3036 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
3037 mStackSupervisor.startSpecificActivityLocked(next, true, true);
3038 }
3039
3040 return true;
3041 }
通过源码,我们可以得知:
- 先对上一个
Activity
执行pause
操作 - 再启动目标
activity
, - 最终进入到了
ActivityStackSupervior.startSpecificActivityLocked()
方法中。 - 在启动Activity之前,调用了
next.showStartingWindow()
方法来展示一个window
,
这就是冷启动时出现白屏的原因。
2.3 进程启动与Activity启动的节点
2.3.1 ActivityStackSupervisor的startSpecificActivityLocked()
我们继续往下追踪ActivityStackSupervisor
的startSpecificActivityLocked()
方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
......
956 void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
957 // Is this activity's application already running?
// 根据进程名和进程id判断目标进程是否已经创建,如果没有则代表进程未创建
958 final WindowProcessController wpc =
959 mService.getProcessController(r.processName, r.info.applicationInfo.uid);
960
961 boolean knownToBeDead = false;
// 如果进程已经创建,这里直接调用realStartActivityLocked去启动Activity
962 if (wpc != null && wpc.hasThread()) {
963 try {
964 realStartActivityLocked(r, wpc, andResume, checkConfig);
965 return;
966 } catch (RemoteException e) {
967 Slog.w(TAG, "Exception when starting activity "
968 + r.intent.getComponent().flattenToShortString(), e);
969 }
......
973 knownToBeDead = true;
974 }
......
979 if (getKeyguardController().isKeyguardLocked()) {
980 r.notifyUnknownVisibilityLaunched();
981 }
982
983 try {
......
// 走到这里说明目标进程未创建,这里使用handler发送消息给ActivityManagerService类,让AMS创建一个新的进程
// 通过发送消息的方式,可避免在ATMS锁被持有的情况下,调用AMS时可能出现的死锁
990 final Message msg = PooledLambda.obtainMessage(
991 ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
992 r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
993 mService.mH.sendMessage(msg);
994 } finally {
995 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
996 }
997 }
......
上面这段方法里有个很重要的判断:if(wpc != null && wpc.hasThread())
。通过进程名和application uid 获取的WindowProcessController
对象进行校验,判断要启动的activity进程是否已启动,分别进行两个关键逻辑:
1. 启动未进程时,启动进程
2. 进程已启动时,启动Activity
显然,app第一次启动时,进程还不存在,首先先得进程启动
。
2.4 进程启动
从上面代码可知,PooledLambda.obtainMessage()
通过Handler
,发送了一条Message
,以避免在ATMS
锁被持有的情况下调用AMS
时可能出现的死锁。这条Message
调用的是ActivityManagerService
的startProcess()
方法,实际调用的是startProcessLocked()
方法,我们直接从它看起:
2.4.1 startProcessLocked()
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
3022 final ProcessRecord startProcessLocked(String processName,
3023 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3024 HostingRecord hostingRecord, boolean allowWhileBooting,
3025 boolean isolated, boolean keepIfLarge) {
3026 return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
3027 hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3028 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3029 null /* crashHandler */);
3030 }
这里调用的是ProcessList
类里的startProcessLocked()
的方法,我们继续往下看。
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
......
1848 @GuardedBy("mService")
1849 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1850 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
1851 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1852 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1853 long startTime = SystemClock.elapsedRealtime();
1854 ProcessRecord app;
......
// 以下三种情况,我们不需要做任何额外的处理
// (1) 存在一个application 记录
// (2) 调用者认为它仍然存活,或者没有线程对象连接到它,所以我们知道它没有crash
// (3) 有一个pid分配给它,所以它要么正在启动,要么已经运行
1900 if (app != null && app.pid > 0) {
1901 if ((!knownToBeDead && !app.killed) || app.thread == null) {
// 我们已经有应用程序在运行,或者正在等待它出现(我们有一个pid,但还没有它的线程),所以保持它
1904 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1905 // If this is a new package in the process, add the package to the list
1906 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1907 checkSlow(startTime, "startProcess: done, added package to proc");
1908 return app;
1909 }
1910
1911 // An application record is attached to a previous process,
1912 // clean it up now.
1913 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1914 checkSlow(startTime, "startProcess: bad proc running, killing");
1915 ProcessList.killProcessGroup(app.uid, app.pid);
1916 mService.handleAppDiedLocked(app, true, true);
1917 checkSlow(startTime, "startProcess: done killing old proc");
1918 }
1919
1920 if (app == null) {
1921 checkSlow(startTime, "startProcess: creating new process record");
// 创建一条ProcessRecord
1922 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
1923 if (app == null) {
1924 Slog.w(TAG, "Failed making new process record for "
1925 + processName + "/" + info.uid + " isolated=" + isolated);
1926 return null;
1927 }
1928 app.crashHandler = crashHandler;
1929 app.isolatedEntryPoint = entryPoint;
1930 app.isolatedEntryPointArgs = entryPointArgs;
1931 checkSlow(startTime, "startProcess: done creating new process record");
1932 } else {
1933 // If this is a new package in the process, add the package to the list
1934 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1935 checkSlow(startTime, "startProcess: added package to existing proc");
1936 }
1937
1938 // If the system is not ready yet, then hold off on starting this
1939 // process until it is.
1940 if (!mService.mProcessesReady
1941 && !mService.isAllowedWhileBooting(info)
1942 && !allowWhileBooting) {
1943 if (!mService.mProcessesOnHold.contains(app)) {
1944 mService.mProcessesOnHold.add(app);
1945 }
1946 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1947 "System not ready, putting on hold: " + app);
1948 checkSlow(startTime, "startProcess: returning with proc on hold");
1949 return app;
1950 }
1951
1952 checkSlow(startTime, "startProcess: stepping in to startProcess");
// 创建一个进程。
1953 final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
1954 checkSlow(startTime, "startProcess: done starting proc!");
1955 return success ? app : null;
1956 }
......
可以看到,在启动一个新的进程时,有两个比较重要的步骤:
- 通过
new ProcessRecordLocked()
方法首先创建一条进程记录 - 然后再通过
startProcessLocked()
方法去创建一个进程。
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
......
1427 @GuardedBy("mService")
1428 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1429 boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1430 String abiOverride) {
......
//
1619 final String entryPoint = "android.app.ActivityThread";
1620
1621 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1622 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1623 startTime);
1624 } catch (RuntimeException e) {
1625 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
......
1633 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1634 false, false, true, false, false, app.userId, "start failure");
1635 return false;
1636 }
1637 }
这里请注意一下entryPoint
这个变量的值————android.app.ActivityThread
,它会经过一段漫长的调用链,最终在RuntimeInit
这个类中发挥它的作用。
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
1640 boolean startProcessLocked(HostingRecord hostingRecord,
1641 String entryPoint,
1642 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1643 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1644 long startTime) {
1645 app.pendingStart = true;
1646 app.killedByAm = false;
1647 app.removed = false;
1648 app.killed = false;
......
1657 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1658 app.setStartParams(uid, hostingRecord, seInfo, startTime);
1659 app.setUsingWrapper(invokeWith != null
1660 || SystemProperties.get("wrap." + app.processName) != null);
1661 mPendingStarts.put(startSeq, app);
1662
1663 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
// 默认以异步方式启动
1666 mService.mProcStartHandler.post(() -> {
1667 try {
1668 final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
1669 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1670 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1671 synchronized (mService) {
1672 handleProcessStartedLocked(app, startResult, startSeq);
1673 }
1674 } catch (RuntimeException e) {
1675 synchronized (mService) {
1676 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1677 + app.processName, e);
1678 mPendingStarts.remove(startSeq);
1679 app.pendingStart = false;
1680 mService.forceStopPackageLocked(app.info.packageName,
1681 UserHandle.getAppId(app.uid),
1682 false, false, true, false, false, app.userId, "start failure");
1683 }
1684 }
1685 });
1686 return true;
1687 } else {
1688 try {
1689 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
1690 entryPoint, app,
1691 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1692 invokeWith, startTime);
1693 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1694 startSeq, false);
1695 } catch (RuntimeException e) {
1696 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1697 + app.processName, e);
1698 app.pendingStart = false;
1699 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1700 false, false, true, false, false, app.userId, "start failure");
1701 }
1702 return app.pid > 0;
1703 }
......
1798 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
1799 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1800 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1801 long startTime) {
1802 try {
1803 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1804 app.processName);
1805 checkSlow(startTime, "startProcess: asking zygote to start proc");
1806 final Process.ProcessStartResult startResult;
// hostingRecord初始化参数为null,
// 并未指定mHostingZygote属性,因此会进入最后一个分支
1807 if (hostingRecord.usesWebviewZygote()) {
1808 startResult = startWebView(entryPoint,
1809 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1810 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1811 app.info.dataDir, null, app.info.packageName,
1812 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1813 } else if (hostingRecord.usesAppZygote()) {
1814 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1815
1816 startResult = appZygote.getProcess().start(entryPoint,
1817 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1818 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1819 app.info.dataDir, null, app.info.packageName,
1820 /*useUsapPool=*/ false,
1821 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1822 } else {
1823 startResult = Process.start(entryPoint,
1824 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1825 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1826 app.info.dataDir, invokeWith, app.info.packageName,
1827 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1828 }
1829 checkSlow(startTime, "startProcess: returned from zygote!");
1830 return startResult;
1831 } finally {
1832 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1833 }
1834 }
hostingRecord
初始化参数为null,并未指定mHostingZygote
属性,因此会进入最后一个分支,调用方法Process.start()
2.4.2 Process的start()方法
/frameworks/base/core/java/android/os/Process.java
521 public static ProcessStartResult start(@NonNull final String processClass,
522 @Nullable final String niceName,
523 int uid, int gid, @Nullable int[] gids,
524 int runtimeFlags,
525 int mountExternal,
526 int targetSdkVersion,
527 @Nullable String seInfo,
528 @NonNull String abi,
529 @Nullable String instructionSet,
530 @Nullable String appDataDir,
531 @Nullable String invokeWith,
532 @Nullable String packageName,
533 @Nullable String[] zygoteArgs) {
534 return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
535 runtimeFlags, mountExternal, targetSdkVersion, seInfo,
536 abi, instructionSet, appDataDir, invokeWith, packageName,
537 /*useUsapPool=*/ true, zygoteArgs);
538 }
其中ZYGOTE_PROCESS
是一个ZygoteProcess
对象,它实际调用的是ZygoteProcess
里的start()
方法。
/frameworks/base/core/java/android/os/ZygoteProcess.java
314 public final Process.ProcessStartResult start(@NonNull final String processClass,
315 final String niceName,
316 int uid, int gid, @Nullable int[] gids,
317 int runtimeFlags, int mountExternal,
318 int targetSdkVersion,
319 @Nullable String seInfo,
320 @NonNull String abi,
321 @Nullable String instructionSet,
322 @Nullable String appDataDir,
323 @Nullable String invokeWith,
324 @Nullable String packageName,
325 boolean useUsapPool,
326 @Nullable String[] zygoteArgs) {
327 // TODO (chriswailes): Is there a better place to check this value?
328 if (fetchUsapPoolEnabledPropWithMinInterval()) {
329 informZygotesOfUsapPoolStatus();
330 }
331
332 try {
333 return startViaZygote(processClass, niceName, uid, gid, gids,
334 runtimeFlags, mountExternal, targetSdkVersion, seInfo,
335 abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
336 packageName, useUsapPool, zygoteArgs);
337 } catch (ZygoteStartFailedEx ex) {
338 Log.e(LOG_TAG,
339 "Starting VM process through Zygote failed");
340 throw new RuntimeException(
341 "Starting VM process through Zygote failed", ex);
342 }
343 }
......
541 private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
542 @Nullable final String niceName,
543 final int uid, final int gid,
544 @Nullable final int[] gids,
545 int runtimeFlags, int mountExternal,
546 int targetSdkVersion,
547 @Nullable String seInfo,
548 @NonNull String abi,
549 @Nullable String instructionSet,
550 @Nullable String appDataDir,
551 @Nullable String invokeWith,
552 boolean startChildZygote,
553 @Nullable String packageName,
554 boolean useUsapPool,
555 @Nullable String[] extraArgs)
556 throws ZygoteStartFailedEx {
557 ArrayList<String> argsForZygote = new ArrayList<>();
558
559 // --runtime-args, --setuid=, --setgid=,
560 // and --setgroups= must go first
561 argsForZygote.add("--runtime-args");
562 argsForZygote.add("--setuid=" + uid);
563 argsForZygote.add("--setgid=" + gid);
564 argsForZygote.add("--runtime-flags=" + runtimeFlags);
565 if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
566 argsForZygote.add("--mount-external-default");
567 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
568 argsForZygote.add("--mount-external-read");
569 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
570 argsForZygote.add("--mount-external-write");
571 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
572 argsForZygote.add("--mount-external-full");
573 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
574 argsForZygote.add("--mount-external-installer");
575 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
576 argsForZygote.add("--mount-external-legacy");
577 }
578
579 argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
580
581 // --setgroups is a comma-separated list
582 if (gids != null && gids.length > 0) {
583 StringBuilder sb = new StringBuilder();
584 sb.append("--setgroups=");
585
586 int sz = gids.length;
587 for (int i = 0; i < sz; i++) {
588 if (i != 0) {
589 sb.append(',');
590 }
591 sb.append(gids[i]);
592 }
593
594 argsForZygote.add(sb.toString());
595 }
596
597 if (niceName != null) {
598 argsForZygote.add("--nice-name=" + niceName);
599 }
600
601 if (seInfo != null) {
602 argsForZygote.add("--seinfo=" + seInfo);
603 }
604
605 if (instructionSet != null) {
606 argsForZygote.add("--instruction-set=" + instructionSet);
607 }
608
609 if (appDataDir != null) {
610 argsForZygote.add("--app-data-dir=" + appDataDir);
611 }
612
613 if (invokeWith != null) {
614 argsForZygote.add("--invoke-with");
615 argsForZygote.add(invokeWith);
616 }
617
618 if (startChildZygote) {
619 argsForZygote.add("--start-child-zygote");
620 }
621
622 if (packageName != null) {
623 argsForZygote.add("--package-name=" + packageName);
624 }
625
626 argsForZygote.add(processClass);
627
628 if (extraArgs != null) {
629 Collections.addAll(argsForZygote, extraArgs);
630 }
631
632 synchronized(mLock) {
633 // The USAP pool can not be used if the application will not use the systems graphics
634 // driver. If that driver is requested use the Zygote application start path.
635 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
636 useUsapPool,
637 argsForZygote);
638 }
639 }
值得注意的是上面这段代码的openZygoteSocketIfNeeded()
这个方法,它采用socket通信方式
,尝试连接路径为/dev/socket/
、名称为zygote
的服务端。
zygoteSendArgsAndGetResult()
方法里实际调用了attemptZygoteSendArgsAndGetResult()
方法,内容如下:
/frameworks/base/core/java/android/os/ZygoteProcess.java
422 private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
423 ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
424 try {
425 final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
426 final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
427
428 zygoteWriter.write(msgStr);
429 zygoteWriter.flush();
430
431 // Always read the entire result from the input stream to avoid leaving
432 // bytes in the stream for future process starts to accidentally stumble
433 // upon.
434 Process.ProcessStartResult result = new Process.ProcessStartResult();
435 result.pid = zygoteInputStream.readInt();
436 result.usingWrapper = zygoteInputStream.readBoolean();
437
438 if (result.pid < 0) {
439 throw new ZygoteStartFailedEx("fork() failed");
440 }
441
442 return result;
443 } catch (IOException ex) {
444 zygoteState.close();
445 Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
446 + ex.toString());
447 throw new ZygoteStartFailedEx(ex);
448 }
449 }
请注意上述方法的zygoteWriter
这个变量,它负责将进程启动参数发送给服务端,由服务端去孵化进程。那么,这个服务端到底是哪个类呢?
答案是ZygoteServer.java
ZygoteServer
会在系统启动的时候,创建一个Socket
服务端,用于接收客户端的fork
请求。ZygoteServer
在初始化结束后,会调用runSelectLoop()
方法,用于处理客户端的消息。当客户端请求fork
进程时,runSelectLoop()
方法会转交给ZygoteConnection
类的processOneCommand()
方法去处理。
Zygote
相关可以参考前面我们分析过的【Android Framework系列】第3章 Zygote进程相关
下面我们继续看
2.4.3 ZygoteConnection的processOneCommand()方法
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
129 Runnable processOneCommand(ZygoteServer zygoteServer) {
130 String args[];
131 ZygoteArguments parsedArgs = null;
132 FileDescriptor[] descriptors;
......
267 pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
268 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
269 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
270 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
271
272 try {
273 if (pid == 0) {
274 // in child
275 zygoteServer.setForkChild();
276
277 zygoteServer.closeServerSocket();
278 IoUtils.closeQuietly(serverPipeFd);
279 serverPipeFd = null;
280
281 return handleChildProc(parsedArgs, descriptors, childPipeFd,
282 parsedArgs.mStartChildZygote);
283 } else {
284 // In the parent. A pid < 0 indicates a failure and will be handled in
285 // handleParentProc.
286 IoUtils.closeQuietly(childPipeFd);
287 childPipeFd = null;
288 handleParentProc(pid, descriptors, serverPipeFd);
289 return null;
290 }
291 } finally {
292 IoUtils.closeQuietly(childPipeFd);
293 IoUtils.closeQuietly(serverPipeFd);
294 }
295 }
通过静态方法Zygote.forkAndSpecialize()
进行程序fork
2.4.4 Zygote的forkAndSpecialize()方法
/frameworks/base/core/java/com/android/internal/os/Zygote.java
234 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
235 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
236 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
237 int targetSdkVersion) {
238 ZygoteHooks.preFork();
239 // Resets nice priority for zygote process.
240 resetNicePriority();
241 int pid = nativeForkAndSpecialize(
242 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
243 fdsToIgnore, startChildZygote, instructionSet, appDataDir);
244 // Enable tracing as soon as possible for the child process.
245 if (pid == 0) {
246 Zygote.disableExecuteOnly(targetSdkVersion);
247 Trace.setTracingEnabled(true, runtimeFlags);
248
249 // Note that this event ends at the end of handleChildProc,
250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
251 }
252 ZygoteHooks.postForkCommon();
253 return pid;
254 }
255
256 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
257 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
258 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
259 String appDataDir);
上述Zygote
类在这个过程中主要做了以下几点工作:
- 调用
dalvik
中ZygoteHooks
的preFrok
进行预处理,主要是停止4个Daemon子线程
:HeapTaskDaemon
、ReferenceQueueDaemon
、FinalizerDaemon
、FinalizerWatchdogDaemon
,等待所有的子线程结束,最后完成gc堆的初始化工作。 - 调用
com_android_internal_os_zygote.cpp
中的nativeForkAndSpecialize
方法,主要工作是通过linux机制fork
一个子进程,以及进程的一些资源处理
,selinux权限处理
,JAVA堆线程的一些处理
。 - 调用
ZygoteHooks
的postForkCommon
方法,启动Zygote的4个Daemon线程
。
在执行forkAndSpecialize()
方法后,代码将继续执行ZygoteConnection
中的handleChildProc()
这个方法。
2.4.5 ZygoteConnection的handleChildProc()方法
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
560 private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
561 FileDescriptor pipeFd, boolean isZygote) {
......
589 if (parsedArgs.mInvokeWith != null) {
590 WrapperInit.execApplication(parsedArgs.mInvokeWith,
591 parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
592 VMRuntime.getCurrentInstructionSet(),
593 pipeFd, parsedArgs.mRemainingArgs);
594
595 // Should not get here.
596 throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
597 } else {
598 if (!isZygote) {
// 进入此分支
599 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
600 parsedArgs.mRemainingArgs, null /* classLoader */);
601 } else {
602 return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
603 parsedArgs.mRemainingArgs, null /* classLoader */);
604 }
605 }
606 }
我们继续往下看ZygoteInit.zygoteInit()
方法
2.4.6 ZygoteInit的zygoteInit()方法
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
972 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
973 ClassLoader classLoader) {
// 初始化运行环境
981 RuntimeInit.commonInit();
// 启动binder线程池
982 ZygoteInit.nativeZygoteInit();
// 程序入口函数
983 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
984 }
2.4.7 RuntimeInit.applicationInit()方法
继续看程序入口函数RuntimeInit.applicationInit()
:
284 protected static Runnable findStaticMain(String className, String[] argv,
285 ClassLoader classLoader) {
286 Class<?> cl;
287
288 try {
289 cl = Class.forName(className, true, classLoader);
290 } catch (ClassNotFoundException ex) {
291 throw new RuntimeException(
292 "Missing class when invoking static main " + className,
293 ex);
294 }
295
296 Method m;
297 try {
298 m = cl.getMethod("main", new Class[] { String[].class });
299 } catch (NoSuchMethodException ex) {
300 throw new RuntimeException(
301 "Missing static main on " + className, ex);
302 } catch (SecurityException ex) {
303 throw new RuntimeException(
304 "Problem getting static main on " + className, ex);
305 }
306
307 int modifiers = m.getModifiers();
308 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
309 throw new RuntimeException(
310 "Main method is not public and static on " + className);
311 }
......
319 return new MethodAndArgsCaller(m, argv);
320 }
......
343 protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
344 ClassLoader classLoader) {
......
350 nativeSetExitWithoutCleanup(true);
......
354 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
355 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
356
357 final Arguments args = new Arguments(argv);
358
359 // The end of of the RuntimeInit event (see #zygoteInit).
360 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
361
362 // Remaining arguments are passed to the start class's static main
363 return findStaticMain(args.startClass, args.startArgs, classLoader);
364 }
这里通过反射
获得了className
变量中的main()
方法,并传递给MethodAndArgsCaller
用于构造一个Runnable
。只要执行此Runnable
,就会开始执行className
变量中的main()
方法。
className
变量的值究竟是什么呢?
还记得我们前文重点强调的entryPoint
这个变量吗?不记得的读者请自行返回再查看一下。android.app.ActivityThread
就是我们要执行的目标类。
ActivityThread
类main
方法的调用,标识着 应用已全部完成进程的创建和初始化过程,下面将进入Application
和Activity
的创建与启动流程。
2.5 Application启动
从2.4中,我们知道ActivityThread
的main()
方法被调用了,程序成功被创建并启动。
2.5.1 ActivityThread的main()
/frameworks/base/core/java/android/app/ActivityThread.java
7310 public static void main(String[] args) {
7311 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
7312
7313 // Install selective syscall interception
7314 AndroidOs.install();
7315
7316 // CloseGuard defaults to true and can be quite spammy. We
7317 // disable it here, but selectively enable it later (via
7318 // StrictMode) on debug builds, but using DropBox, not logs.
7319 CloseGuard.setEnabled(false);
// 初始化应用中需要使用的系统路径
7321 Environment.initForCurrentUser();
7322
7323 // Make sure TrustedCertificateStore looks in the right place for CA certificates
// 为应用设置当前用户的CA证书保存的位置
7324 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
7325 TrustedCertificateStore.setDefaultUserDirectory(configDir);
7326
// 设置进程的名称
7327 Process.setArgV0("<pre-initialized>");
// 主线程Looper准备
7329 Looper.prepareMainLooper();
......
// 创建ActivityThread 对象
7342 ActivityThread thread = new ActivityThread();
7343 thread.attach(false, startSeq);
7344
7345 if (sMainThreadHandler == null) {
7346 sMainThreadHandler = thread.getHandler();
7347 }
......
// 主线程Looper,开启消息循环
7356 Looper.loop();
7357
7358 throw new RuntimeException("Main thread loop unexpectedly exited");
7359 }
......
2.5.2 ActivityThread的attach()
main()
方法内调用了attach()
方法
/frameworks/base/core/java/android/app/ActivityThread.java
7071 private void attach(boolean system, long startSeq) {
7072 sCurrentActivityThread = this;
7073 mSystemThread = system;
7074 if (!system) {
7075 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
7076 UserHandle.myUserId());
// 把对象mAppThread(Binder)放到了RuntimeInit类中的静态变量mApplicationObject中
7077 RuntimeInit.setApplicationObject(mAppThread.asBinder());
7078 final IActivityManager mgr = ActivityManager.getService();
7079 try {
// 关键:通过Binder调用AMS的attachApplication()方法
7080 mgr.attachApplication(mAppThread, startSeq);
7081 } catch (RemoteException ex) {
7082 throw ex.rethrowFromSystemServer();
7083 }
......
7106 } else {
7107 // Don't set application object here -- if the system crashes,
7108 // we can't display an alert, we just want to die die die.
7109 android.ddm.DdmHandleAppName.setAppName("system_process",
7110 UserHandle.myUserId());
7111 try {
7112 mInstrumentation = new Instrumentation();
7113 mInstrumentation.basicInit(this);
7114 ContextImpl context = ContextImpl.createAppContext(
7115 this, getSystemContext().mPackageInfo);
7116 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
7117 mInitialApplication.onCreate();
7118 } catch (Exception e) {
7119 throw new RuntimeException(
7120 "Unable to instantiate Application():" + e.toString(), e);
7121 }
7122 }
......
7144 }
7145
ActivityThread
类的attach
方法内,通过binder
调用AMS
的attachApplication
方法进行Application
的初始化。我们来看看:
2.5.3 ActivityManagerService的attachApplication()
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
5179 @Override
5180 public final void attachApplication(IApplicationThread thread, long startSeq) {
5181 if (thread == null) {
5182 throw new SecurityException("Invalid application interface");
5183 }
5184 synchronized (this) {
5185 int callingPid = Binder.getCallingPid();
5186 final int callingUid = Binder.getCallingUid();
5187 final long origId = Binder.clearCallingIdentity();
5188 attachApplicationLocked(thread, callingPid, callingUid, startSeq);
5189 Binder.restoreCallingIdentity(origId);
5190 }
5191 }
2.5.4 ActivityManagerService的attachApplicationLocked()
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
4767 private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
4768 int pid, int callingUid, long startSeq) {
......
5046 if (app.isolatedEntryPoint != null) {
5047 // This is an isolated process which should just call an entry point instead of
5048 // being bound to an application.
5049 thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
5050 } else if (instr2 != null) {
// 1.调用ApplicationThread的bindApplication去初始化Application
5051 thread.bindApplication(processName, appInfo, providers,
5052 instr2.mClass,
5053 profilerInfo, instr2.mArguments,
5054 instr2.mWatcher,
5055 instr2.mUiAutomationConnection, testMode,
5056 mBinderTransactionTrackingEnabled, enableTrackAllocation,
5057 isRestrictedBackupMode || !normalMode, app.isPersistent(),
5058 new Configuration(app.getWindowProcessController().getConfiguration()),
5059 app.compat, getCommonServicesLocked(app.isolated),
5060 mCoreSettingsObserver.getCoreSettingsLocked(),
5061 buildSerial, autofillOptions, contentCaptureOptions);
5062 } else {
5063 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
5064 null, null, null, testMode,
5065 mBinderTransactionTrackingEnabled, enableTrackAllocation,
5066 isRestrictedBackupMode || !normalMode, app.isPersistent(),
5067 new Configuration(app.getWindowProcessController().getConfiguration()),
5068 app.compat, getCommonServicesLocked(app.isolated),
5069 mCoreSettingsObserver.getCoreSettingsLocked(),
5070 buildSerial, autofillOptions, contentCaptureOptions);
5071 }
5072 if (profilerInfo != null) {
5073 profilerInfo.closeFd();
5074 profilerInfo = null;
5075 }
5076
5077 // Make app active after binding application or client may be running requests (e.g
5078 // starting activities) before it is ready.
5079 app.makeActive(thread, mProcessStats);
5080 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
5081 mProcessList.updateLruProcessLocked(app, false, null);
5082 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
5083 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5084 } catch (Exception e) {
......
5093 return false;
5094 }
5095
5096 // Remove this record from the list of starting applications.
5097 mPersistentStartingProcesses.remove(app);
5098 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5099 "Attach application locked removing on hold: " + app);
5100 mProcessesOnHold.remove(app);
5101
5102 boolean badApp = false;
5103 boolean didSomething = false;
5104
5105 // See if the top visible activity is waiting to run in this process...
5106 if (normalMode) {
5107 try {
// 2.去启动Activity
5108 didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
5109 } catch (Exception e) {
5110 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5111 badApp = true;
5112 }
5113 }
......
5176 return true;
5177 }
上面代码主要做了两件事:
- 调用了
ApplicationThread
的bindApplication()
方法去初始化Application
,又是一次跨进程调用。 - 通过
ATMS
去启动目标Activity
。
先来分析ApplicationThread
的bindApplication()
方法
2.5.5 ActivityThread的bindApplication()
/frameworks/base/core/java/android/app/ActivityThread.java
996 public final void bindApplication(String processName, ApplicationInfo appInfo,
997 List<ProviderInfo> providers, ComponentName instrumentationName,
998 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
999 IInstrumentationWatcher instrumentationWatcher,
1000 IUiAutomationConnection instrumentationUiConnection, int debugMode,
1001 boolean enableBinderTracking, boolean trackAllocation,
1002 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
1003 CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
1004 String buildSerial, AutofillOptions autofillOptions,
1005 ContentCaptureOptions contentCaptureOptions) {
......
// 通过handler发消息,启动Application
1053 sendMessage(H.BIND_APPLICATION, data);
1054 }
......
1855 switch (msg.what) {
1856 case BIND_APPLICATION:
1857 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1858 AppBindData data = (AppBindData)msg.obj;
1859 handleBindApplication(data);
1860 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1861 break;
}
......
@UnsupportedAppUsage
6122 private void handleBindApplication(AppBindData data) {
......
6379 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
6380 appContext.getClassLoader(), false, true, false);
......
6385 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
6386 appContext.getOpPackageName());
6387
6388 try {
6389 final ClassLoader cl = instrContext.getClassLoader();
// 创建仪表
6390 mInstrumentation = (Instrumentation)
6391 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
6392 } catch (Exception e) {
......
6396 }
6397
6398 final ComponentName component = new ComponentName(ii.packageName, ii.name);
// 初始化仪表盘
6399 mInstrumentation.init(this, instrContext, appContext, component,
6400 data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
......
6412 }
......
6425 Application app;
......
6428 try {
6429 // If the app is being launched for full backup or restore, bring it up in
6430 // a restricted environment with the base application class.
// 创建Application
6431 app = data.info.makeApplication(data.restrictedBackupMode, null);
......
6451 try {
6452 mInstrumentation.onCreate(data.instrumentationArgs);
6453 }
6454 catch (Exception e) {
......
6458 }
6459 try {
// 调用Application的onCreate方法
6460 mInstrumentation.callApplicationOnCreate(app);
6461 } catch (Exception e) {
...
6467 }
6468 } finally {
....
6475 }
6497 }
......
主要做了三件事:
- 创建仪表盘。
- 使用
LoadedApk
创建一个Application
,不过最终还是使用的仪表盘利用反射创建的Application
类。 - 使用仪表盘初始化
Application
,点击去可以查看下mInstrumentation.callApplicationOnCreate()
方法。
2.5.6 Instrumentation的callApplicationOnCreate()
/frameworks/base/core/java/android/app/Instrumentation.java
1181 public void callApplicationOnCreate(Application app) {
1182 app.onCreate();
1183 }
到这里,Application
即初始化完成。
2.5.7 Application启动后,跟着继续启动第一个Activity
AMS
的attachApplicationLocked()
做了两件事:
- Application创建已经完成。
- 通过ATMS启动程序的第一个Activity
拿我们继续往下看Activity的启动:
这里mAtmInternal.attachApplication(app.getWindowProcessController())
中的mAtmInternal
是LocalService
类对象是ATMS的子类,继承自ActivityTaskManagerInternal
。
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
6078 final class LocalService extends ActivityTaskManagerInternal {
......
6866 @Override
6867 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
6868 synchronized (mGlobalLockWithoutBoost) {
6869 return mRootActivityContainer.attachApplication(wpc);
6870 }
6871 }
}
这个方法只做了一件事,调用RootActivityContainer
的attachApplication()
方法,我们继续看看:
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
768 boolean attachApplication(WindowProcessController app) throws RemoteException {
769 final String processName = app.mName;
770 boolean didSomething = false;
771 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
772 final ActivityDisplay display = mActivityDisplays.get(displayNdx);
773 final ActivityStack stack = display.getFocusedStack();
774 if (stack != null) {
775 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
776 final ActivityRecord top = stack.topRunningActivityLocked();
777 final int size = mTmpActivityList.size();
778 for (int i = 0; i < size; i++) {
779 final ActivityRecord activity = mTmpActivityList.get(i);
780 if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
781 && processName.equals(activity.processName)) {
782 try {
783 if (mStackSupervisor.realStartActivityLocked(activity, app,
784 top == activity /* andResume */, true /* checkConfig */)) {
785 didSomething = true;
786 }
787 } catch (RemoteException e) {
788 Slog.w(TAG, "Exception in new application when starting activity "
789 + top.intent.getComponent().flattenToShortString(), e);
790 throw e;
791 }
792 }
793 }
794 }
795 }
796 if (!didSomething) {
797 ensureActivitiesVisible(null, 0, false /* preserve_windows */);
798 }
799 return didSomething;
800 }
可以看到这里调用了ActivityStackSupervisor
的realStartActivityLocked()
方法
到这里就和我们在2.3中ActivityStackSupervisor
的startSpecificActivityLocked()
方法内的第二个分支一致了。
有两个分支:
- 进程未启动,则使用handler发message给AMS通知创建进程;(2.4中已分析)
- 进程已启动,则启动Activity。
下面我们来看看Activity的启动:
2.6 Activity启动
2.6.1 ActivityStackSupervisor的realStartActivityLocked()
startSpecificActivityLocked()
方法内调用了realStartActivityLocked()
,我们来看看这个方法:
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
705 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
706 boolean andResume, boolean checkConfig) throws RemoteException {
......
// 创建一个Activity启动事务,同时传入proc.getThread(),
// 该对象实际为ApplicationThread
828 final ClientTransaction clientTransaction = ClientTransaction.obtain(
829 proc.getThread(), r.appToken);
830
831 final DisplayContent dc = r.getDisplay().mDisplayContent;
// 把LaunchActivityItem加入事务中,
// 后面会调用到该类的handleLaunchActivity()方法
832 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
833 System.identityHashCode(r), r.info,
834 // TODO: Have this take the merged configuration instead of separate global
835 // and override configs.
836 mergedConfiguration.getGlobalConfiguration(),
837 mergedConfiguration.getOverrideConfiguration(), r.compat,
838 r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
839 r.icicle, r.persistentState, results, newIntents,
840 dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
841 r.assistToken));
842
843 // Set desired final state.
844 final ActivityLifecycleItem lifecycleItem;
845 if (andResume) {
846 lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
847 } else {
848 lifecycleItem = PauseActivityItem.obtain();
849 }
850 clientTransaction.setLifecycleStateRequest(lifecycleItem);
851
// 在这里启动事务
853 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
929 return true;
930 }
重点代码做了注释,可以看到在这段代码中,主要是创建事务
,同时传入ApplicationThread
,而ApplicationThread
继承于Binder
,这里传入目的主要后面用来跟目标APP进程通信。然后就是启动事务,mService.getLifecycleManager()
方法返回的是ClientLifecycleManager
对象,接下来继续分析ClientLifecycleManager
的scheduleTransaction()
方法
2.6.2 scheduleTransaction()
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
45 void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
46 final IApplicationThread client = transaction.getClient();
47 transaction.schedule();
48 if (!(client instanceof Binder)) {
49 // If client is not an instance of Binder - it's a remote call and at this point it is
50 // safe to recycle the object. All objects used for local calls will be recycled after
51 // the transaction is executed on client in ActivityThread.
52 transaction.recycle();
53 }
54 }
在ClientLifecycleManager
类的scheduleTransaction()
方法中可以明确看到,这里实际调用了ClientTransaction
对象的schedule()
方法,进入到ClientTransaction
的schedule()
方法继续分析。
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
134 public void schedule() throws RemoteException {
135 mClient.scheduleTransaction(this);
136 }
在ClientTransaction
类的schedule()
方法里,又调用了mClient
的scheduleTransaction()
方法,而这个mClient实际就是在创建Activity启动事务时传入的ApplicationThread
对象,也就是说,这里开始从AMS进程
跨进程调用ApplicationThread
的scheduleTransaction()
方法**(第二次跨进程)**,接下来进入到ApplicationThread
的scheduleTransaction()
方法中分析。
/frameworks/base/core/java/android/app/ActivityThread.java
904 private class ApplicationThread extends IApplicationThread.Stub {
1665 public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
1666 ActivityThread.this.scheduleTransaction(transaction);
1667 }
}
ApplicationThread
是ActivityThread
的内部类,继承于IApplicationThread.Stub
,而IApplicationThread.Stub
又继承于Binder
,所以本质还是一个Binder
,用来在ActivityThread
和AMS
之间通信。继续分析scheduleTransaction()
方法,这里又调用了ActivityThread
的scheduleTransaction()
方法,实际上ActivityThread
是父类ClientTransactionHandler
的方法,点进去分析。
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
45 void scheduleTransaction(ClientTransaction transaction) {
46 transaction.preExecute(this);
47 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
48 }
在这个方法里发送handler
消息H.EXECUTE_TRANSACTION
,并且Message
中的obj
就是启动 Activity
的事务对象。而这个Handler
的具体实现是ActivityThread
中的H
对象,接着找到接收handle
消息的地方继续分析。
2.6.3 ActivityThread中处理Handler消息
/frameworks/base/core/java/android/app/ActivityThread.java
1853 public void handleMessage(Message msg) {
1854 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1855 switch (msg.what) {
......
2014 case EXECUTE_TRANSACTION:
2015 final ClientTransaction transaction = (ClientTransaction) msg.obj;
2016 mTransactionExecutor.execute(transaction);
2017 if (isSystem()) {
2018 // Client transactions inside system process are recycled on the client side
2019 // instead of ClientLifecycleManager to avoid being cleared before this
2020 // message is handled.
2021 transaction.recycle();
2022 }
2023 // TODO(lifecycler): Recycle locally scheduled transactions.
2024 break;
......
2031 }
接收handler消息的地方定义在ActivityThread
类中,在这里,又调用了TransactionExecutor
的execute()
方法,点进去继续分析
2.6.4 TransactionExecutor的execute
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
69 public void execute(ClientTransaction transaction) {
......
95 executeCallbacks(transaction);
96
97 executeLifecycleState(transaction);
98 mPendingActions.clear();
99 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
100 }
......
104 public void executeCallbacks(ClientTransaction transaction) {
......
124 final int size = callbacks.size();
125 for (int i = 0; i < size; ++i) {
126 final ClientTransactionItem item = callbacks.get(i);
127 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
128 final int postExecutionState = item.getPostExecutionState();
129 final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
130 item.getPostExecutionState());
131 if (closestPreExecutionState != UNDEFINED) {
132 cycleToPath(r, closestPreExecutionState, transaction);
133 }
// item的类型其实就是LaunchActivityItem
135 item.execute(mTransactionHandler, token, mPendingActions);
136 item.postExecute(mTransactionHandler, token, mPendingActions);
......
148 }
149 }
在executeCallback()
方法中,会遍历事务中的callback
并执行execute
方法,这些callbacks
是在前面创建Activity启动事务
时添加,添加的callback
对象其实就是ClientTransactionItem
类的子类LaunchActivityItem
的对象。
所以,item.execute(mTransactionHandler, token, mPendingActions)
,就是调用了LaunchActivityItem
类的execute()
方法,进入LaunchActivityItem
类的execute()
方法继续分析。
2.6.5 LaunchActivityItem的execute()
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
76 public void execute(ClientTransactionHandler client, IBinder token,
77 PendingTransactionActions pendingActions) {
78 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
79 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
80 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
81 mPendingResults, mPendingNewIntents, mIsForward,
82 mProfilerInfo, client, mAssistToken);
// 注意这里:启动Activity
83 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
84 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
85 }
在LaunchActivityItem
类的execute()
方法里,调用了client.handleLaunchActivity()
方法,这里的client
为ClientTransactionHandler
类型,而ClientTransactionHandler
的实现类是ActivityThread
,所以这里又回到了ActivityThread
类,并调用了handleLaunchActivity()
方法,继续分析。
2.6.6 ActivityThread的handleLaunchActivity()
/frameworks/base/core/java/android/app/ActivityThread.java
3380 @Override
3381 public Activity handleLaunchActivity(ActivityClientRecord r,
3382 PendingTransactionActions pendingActions, Intent customIntent) {
......
// 初始化 Activity 的 WindowManager,每一个 Activity 都会对应一个“窗口”
3404 WindowManagerGlobal.initialize();
// 这里是重点
3409 final Activity a = performLaunchActivity(r, customIntent);
......
3430 return a;
3431 }
2.6.7 ActivityThread的performLaunchActivity()
/frameworks/base/core/java/android/app/ActivityThread.java
3158 /** Core implementation of activity launch. */
3159 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
3178 ContextImpl appContext = createBaseContextForActivity(r);
3179 Activity activity = null;
3180 try {
// 1.通过反射创建目标 Activity 对象
3181 java.lang.ClassLoader cl = appContext.getClassLoader();
3182 activity = mInstrumentation.newActivity(
3183 cl, component.getClassName(), r.intent);
3184 StrictMode.incrementExpectedActivityCount(activity.getClass());
3185 r.intent.setExtrasClassLoader(cl);
3186 r.intent.prepareToEnterProcess();
3187 if (r.state != null) {
3188 r.state.setClassLoader(cl);
3189 }
3190 } catch (Exception e) {
......
3196 }
3197
3198 try {
3199 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
.......
3209 if (activity != null) {
......
// 2.创建window
3217 Window window = null;
3218 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
3219 window = r.mPendingRemoveWindow;
3220 r.mPendingRemoveWindow = null;
3221 r.mPendingRemoveWindowManager = null;
3222 }
3223 appContext.setOuterContext(activity);
// 3.调用 attach 方法建立 Activity 与 Context 之间的联系,
// 创建 PhoneWindow 对象,并与 Activity 进行关联操作
3224 activity.attach(appContext, this, getInstrumentation(), r.token,
3225 r.ident, app, r.intent, r.activityInfo, title, r.parent,
3226 r.embeddedID, r.lastNonConfigurationInstances, config,
3227 r.referrer, r.voiceInteractor, window, r.configCallback,
3228 r.assistToken);
.......
3236 int theme = r.activityInfo.getThemeResource();
3237 if (theme != 0) {
// 设置主题
3238 activity.setTheme(theme);
3239 }
3240
3241 activity.mCalled = false;
// 4.通过 Instrumentation 最终调用 Activity 的 onCreate 方法
3242 if (r.isPersistable()) {
3243 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3244 } else {
3245 mInstrumentation.callActivityOnCreate(activity, r.state);
3246 }
3247 if (!activity.mCalled) {
3248 throw new SuperNotCalledException(
3249 "Activity " + r.intent.getComponent().toShortString() +
3250 " did not call through to super.onCreate()");
3251 }
3252 r.activity = activity;
3253 }
......
3266 } catch (Exception e) {
......
3272 }
3273
3274 return activity;
3275 }
主要代码已经加了注释,主要做了以下这些事情,
- 使用反射创建目标
Activity
对象; - 创建
PhoneWindow
对象, - 调用
attach
方法绑定Activity
; - 调用
Activity
的onCreate
方法
步骤4中,是通过Instrumentation
来调用的Activity
的onCreate()
方法,点进去看下callActivityOnCreate()
方法。
2.6.8 Instrumentation的callActivityOnCreate()
/frameworks/base/core/java/android/app/Instrumentation.java
1297 public void callActivityOnCreate(Activity activity, Bundle icicle) {
1298 prePerformCreate(activity);
1299 activity.performCreate(icicle);
1300 postPerformCreate(activity);
1301 }
......
1310 public void callActivityOnCreate(Activity activity, Bundle icicle,
1311 PersistableBundle persistentState) {
1312 prePerformCreate(activity);
1313 activity.performCreate(icicle, persistentState);
1314 postPerformCreate(activity);
1315 }
可以看到调用了Activity
的performCreate()
方法,进入performCreate()
方法查看:
/frameworks/base/core/java/android/app/Activity.java
7795 final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
// 在这里调用了Activity的生命周期onCreate方法
7799 if (persistentState != null) {
7800 onCreate(icicle, persistentState);
7801 } else {
7802 onCreate(icicle);
7803 }
......
7812 }
到这里,Activity
已经被创建调用了onCreate()
方法,并开始了生命周期的回调
3 总结
由于涉及的类和方法太多,我就简单总结一下Launcher启动的整体流程:
SystemServer
将AMS
启动后,AMS
开始启动Launcher
.AMS
判断目标Activity
所属进程是否存在,不存在就去通知Zygote
进程创建一个新的进程。- 新的进程进入
ActivityThread
的main()
入口,初始化Looper
,并通知AMS
进程去初始化Application
。 - 同时
AMS
又去执行Activity启动
,接着通知ApplicationThread
启动目标Activity
。 ActivityThread
收到通知,执行Activity
的创建、初始化操作。