Android系统启动(四) — Launcher 启动过程

news/2024/10/30 21:30:36/

1 Launcher 概述

系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 LauncherLauncher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。

通俗的讲,Launcher 就是 Android 系统的桌面, 它的作用主要有以下两点:

  • 作为 Android 系统的启动器,用于启动应用程序;
  • 作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件;

2 Launcher 启动过程

SystemServer 进程在启动的过程中会启动 PackageManagerServicePackageManagerService 启动后会将系统中的应用程序安装完成,在此之前已经启动的 ActivityManagerService 会将 Launcher 启动起来。

Launcher 的启动分为三个部分:

  • SystemServer 完成启动 Launcher Activity 的相关配置;
  • Zygote 进程 forkLauncher 进程;
  • 进入 ActivityThread.main 函数,最终完成 LauncheronCreate 操作;

第一阶段 完成 Launcher 的相关配置

图1

SystemServer.startOtherServices 方法中调用 ActivityManagerService.systemReady方法,Launcher 进程的启动就是从这里开始的,以下是相关源码:

// /frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {...mActivityManagerService.systemReady(() -> { // 1Slog.i(TAG, "Making services ready");traceBeginAndSlog("StartActivityManagerReadyPhase");mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);traceEnd();}...}                                                      

以下是 ActivityManagerService.systemReady 方法的源码:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityTaskManagerInternal mAtmInternal;
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {...// 启动 Home Activity,即 Launcher 应用的入口 Activity,这里指的是,在所有屏幕上启动 Launcher。因为 Android 10 开始支持多屏幕,比如手机屏幕、虚拟投屏、外接屏幕mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); // 1...
}

这里的 mAtmInternalActivityTaskManagerInternal 的实例,ActivityTaskManagerInternal 是一个抽象类。 ActivityManagerService 中的内部类 LocalService 实现了 ActivityTaskManagerInternal

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {...@Overridepublic boolean startHomeOnAllDisplays(int userId, String reason) {synchronized (mGlobalLock) {return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);}}...
}

LocalService.startHomeOnAllDisplays 方法中调用了 RootActivityContainer.startHomeOnAllDisplays 方法。RootActivityContainer 的作用是,调用 PackageManagerService 中去查询手机系统中已经安装的应用哪一个符合 Launcher 标准,且返回一个 Intent 对象,并且交给 ActivityStarter

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {boolean homeStarted = false;for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {final int displayId = mActivityDisplays.get(i).mDisplayId;homeStarted |= startHomeOnDisplay(userId, reason, displayId); // 1}return homeStarted;
}boolean startHomeOnDisplay(int userId, String reason, int displayId) {return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,false /* fromHomeKey */);
}boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey) {...Intent homeIntent = null;ActivityInfo aInfo = null;if (displayId == DEFAULT_DISPLAY) {// 构建一个 category 为 CATEGORY_HOME 的 Intent,表明是 HomeActivityhomeIntent = mService.getHomeIntent(); // 2// 通过 PMS 从系统所有已安装的引用中找到一个符合 homeIntent 的 ActivityaInfo = resolveHomeActivity(userId, homeIntent); // 3} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {...}...// 启动 LaunchermService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, displayId); // 4return true;
}

在注释 2 处调用了 ActivityTaskManagerService.getHomeIntent() 方法来构建一个 categoryCATEGORY_HOMEIntent,表明是一个符合 Launcher 应用的 Intent。在注释 3 处通过调用 resolveHomeActivity 方法解析出需要启动 Activity 的信息。在注释 4 处调用 ActivityTaskManagerService.getActivityStartController() 获取 ActivityStartController,这个类的作用就是做启动前的各项检查,比如,Activity 是否有清单文件注册,Class 文件是否存在等,之后启动 Activity

以下是相关的时序图:

图2

首先,看一下 ActivityTaskManagerService.getHomeIntent() 方法,主要是构建一个符合 Launcher 应用的 Intent

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
Intent getHomeIntent() {Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {intent.addCategory(Intent.CATEGORY_HOME); // 1}return intent;
}     

在注释 1 处代表的是要启动 Activity 的意图,通常来说,整个系统只会有一个应用在清单文件中配置 CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪一个应用作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用。

接着看 RootActivityContainer.resolveIntentInternal 方法:

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,int flags, int userId, boolean resolveForStart, int filterCallingUid) {try {Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");if (!sUserManager.exists(userId)) return null;final int callingUid = Binder.getCallingUid();flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);mPermissionManager.enforceCrossUserPermission(callingUid, userId,false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);final ResolveInfo bestChoice =chooseBestActivity(intent, resolvedType, flags, query, userId);return bestChoice;} finally {Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}
}

通过 Binder 跨进程通信通知 PackageManagerService 从系统所有已经安装的应用中找到一个符合 homeInentActivity

再看 ActivityStartController.startHomeActivity 的代码:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {final ActivityOptions options = ActivityOptions.makeBasic();options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);if (!ActivityRecord.isResolverActivity(aInfo.name)) {options.setLaunchActivityType(ACTIVITY_TYPE_HOME);}options.setLaunchDisplayId(displayId);mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) // 1.setOutActivity(tmpOutRecord).setCallingUid(0).setActivityInfo(aInfo).setActivityOptions(options.toBundle()).execute(); // 2mLastHomeActivityStartRecord = tmpOutRecord[0];final ActivityDisplay display =mService.mRootActivityContainer.getActivityDisplay(displayId);final ActivityStack homeStack = display != null ? display.getHomeStack() : null;if (homeStack != null && homeStack.mInResumeTopActivity) { mSupervisor.scheduleResumeTopActivities();}
}ActivityStarter obtainStarter(Intent intent, String reason) { // 3return mFactory.obtain().setIntent(intent).setReason(reason);
}

在注释 1 处先获取一个 ActivityStarter ,主要用于启动 Activity,然后把需要的参数设置进去,最后再调用它的 execute() 方法:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {try {if (mRequest.mayWait) {...} else {return startActivity(...);}} finally {onExecutionComplete();}
}

以下是 ActivityStarter.startActivity 的相关源码,这个方法主要是用来做 Activity 启动之前的安全校验:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(...) {mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);int err = ActivityManager.START_SUCCESS;// Pull the optional Ephemeral Installer-only bundle out of the options early.final Bundle verificationBundle= options != null ? options.popAppVerificationBundle() : null;WindowProcessController callerApp = null;if (caller != null) {callerApp = mService.getProcessController(caller);if (callerApp != null) {callingPid = callerApp.getPid();callingUid = callerApp.mInfo.uid;} else {Slog.w(TAG, "Unable to find app for caller " + caller+ " (pid=" + callingPid + ") when starting: "+ intent.toString());err = ActivityManager.START_PERMISSION_DENIED;}}...final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);...
}private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity,boolean restrictedBgActivity) {...result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity, restrictedBgActivity); // 1...
}

注释 1 处调用了 ActivityStarter.startActivityUnchecked 的代码:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) {...final int preferredWindowingMode = mLaunchParams.mWindowingMode;computeLaunchingTaskFlags(); // 1computeSourceStack(); // 2mIntent.setFlags(mLaunchFlags);ActivityRecord reusedActivity = getReusableIntentActivity();...mRootActivityContainer.resumeFocusedStacksTopActivities(); // 3...
}

注释 1 处的 ActivityStarter.computeLaunchingTaskFlags() 方法是根据 Activitylauncher modeintent.flag 计算出 Activity 的入栈方式。注释 2 处的 ActivityStarter.computeSourceStack() 计算从哪个栈中启动该 Activity。注释 3 处调用了 RootActivityContainer.resumeFocusedStacksTopActivities 方法:

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities() {return resumeFocusedStacksTopActivities(null, null, null);
}boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {...if (targetStack != null && (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() == targetStack)) {result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {...if (!resumedOnDisplay) {final ActivityStack focusedStack = display.getFocusedStack(); if (focusedStack != null) {focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); // 1}}}return result;
}

在注释 1 处调用 ActivityStack.resumeTopActivityUncheckedLocked 方法:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {...result = resumeTopActivityInnerLocked(prev, options);...
}@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {...if (anim) {next.applyOptionsLocked();} else {next.clearOptionsLocked();}mStackSupervisor.mNoAnimActivities.clear();if (next.attachedToProcess()) { // 待启动的进程是否创建完成,如果没有就会到 else 中...}  else {mStackSupervisor.startSpecificActivityLocked(next, true, true); // 1}...
}

在注释 1 处调用 ActivityStackSupervisor.startSpecificActivityLocked

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume,boolean checkConfig) {...try {...final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,  // 1mService.mAmInternal, r.processName, r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());mService.mH.sendMessage(msg);} finally {Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}
}

注释 1 出调用的其实是 ActivityManagerService.startProcess 方法,开始创建进程:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {@Overridepublic void startProcess(String processName, ApplicationInfo info,boolean knownToBeDead, String hostingType, ComponentName hostingName) {try {if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"+ processName);}synchronized (ActivityManagerService.this) {startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName),false /* allowWhileBooting */, false /* isolated */,true /* keepIfLarge */); // 1}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}@GuardedBy("this")final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) {return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,null /* crashHandler */); // 2}
}

在注释 1 处调用 LocalService.startProcessLocked 方法。在 LocalService.startProcessLocked 方法中又把进程创建的工作委派给了 ProcessList。接着看 ProcessList.startProcessLocked 方法:

// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {startProcessLocked(app, hostingRecord, null /* abiOverride */);
}@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,String abiOverride) {return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */,false /* mountExtStorageFull */, abiOverride);
}@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,boolean disableHiddenApiChecks, boolean mountExtStorageFull,String abiOverride) {...final String entryPoint = "android.app.ActivityThread"; // 1return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime);
}@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {if (!isolated) {app = getProcessRecordLocked(processName, info.uid, keepIfLarge);checkSlow(startTime, "startProcess: after getProcessRecord");...}final String entryPoint = "android.app.ActivityThread";...
}

这几个方法的作用是在进程创建之前,配置一些必要的参数,比如版本号之类的参数。在注释 1 处是一个非常重要的参数,entryPoint 是新进程的入口。所以,Android 应用的程序入口是 ActivityThread

创建进程所需的参数配置完成后,最终会走到 ZygoteProcess 类中:

private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,@Nullable final String niceName,final int uid, final int gid,@Nullable final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,@Nullable String seInfo,@NonNull String abi,@Nullable String instructionSet,@Nullable String appDataDir,@Nullable String invokeWith,boolean startChildZygote,@Nullable String packageName,boolean useUsapPool,@Nullable String[] extraArgs)throws ZygoteStartFailedEx {synchronized (mLock) {return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),useUsapPool, argsForZygote);}
}

此时还处于 system_server进程,这个类的目的是创建本地的 Socket 连接对象,连接到 Zygote 进程的 Socket 方法,然后通过字符输入流,把创建进程所需要的参数发送过去。

第二阶段:Zygote 进程 fork 一个 Launcher 进程的阶段

system_server 进程的 AMS 服务向 Zygote 进程发出 fork 出一个新进程的请求。由于 Zygote 进程在启动的时候会创建 Java 虚拟机,因此,通过 fork 创建出来的程序进程可以在内部获取一个 Java 虚拟机的实例拷贝。fork 采用 copy-on-write 机制,如果数据不发生变化,子进程和父进程可以共享一份数据,从而省去不少内存。

以下是 ZygoteInit.main 函数:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {...Runnable caller;...if (startSystemServer) {// Zygote fork 出的第一个进程是 system_serverRunnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}}...// 循环等待 fork 出其他的应用进程,比如 Launcher,最终通过调用 processOneCommand 来进行进程的处理caller = zygoteServer.runSelectLoop(abiList);...if (caller != null) {// 执行返回的 Runnable 对象,进入子进程caller.run();}...
}

Zygoteforksystem_server 进程,接着进入循环等待,用来接收 Socket 发来的消息,用来 fork 其他进程,比如 Launcher 进程。

// /frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {...final Runnable command = connection.processOneCommand(this);...
}

接着调用 ZygoteConnection.processOneCommand 方法:

// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {...int pid = -1;...// fork 子进程,得到一个新的 pidpid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);...try {if (pid == 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;return handleChildProc(parsedArgs, descriptors, childPipeFd,parsedArgs.mStartChildZygote);} else {// In the parent. A pid < 0 indicates a failure and will be handled in// handleParentProc.IoUtils.closeQuietly(childPipeFd);childPipeFd = null;handleParentProc(pid, descriptors, serverPipeFd);return null;}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}
}

通过调用 Zygote.forkAndSpecializeforkLauncher 进程,并执行 ZygoteConnection.handleChildProc 方法,进入子进程的处理:

// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {...if (parsedArgs.mInvokeWith != null) {WrapperInit.execApplication(parsedArgs.mInvokeWith, parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,VMRuntime.getCurrentInstructionSet(),pipeFd, parsedArgs.mRemainingArgs);// Should not get here.throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");} else {if (!isZygote) {// APP 进程将会调用到这里,执行目标类的 main 方法return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */); // 1} else {return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);}}}
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // 1
}

进入子进程的操作,最终获得需要执行的 ActivityThread.main 方法,然后把之前传来的 android.app.ActivityThread 传递给 findStaticMain

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {...// Remaining arguments are passed to the start class's static mainreturn findStaticMain(args.startClass, args.startArgs, classLoader);
}

通过反射,拿到 ActivityThread.main 方法:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class<?> cl;try {cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className,ex);}Method m;try {m = cl.getMethod("main", new Class[] { String[].class });} catch (NoSuchMethodException ex) {throw new RuntimeException("Missing static main on " + className, ex);} catch (SecurityException ex) {throw new RuntimeException("Problem getting static main on " + className, ex);}int modifiers = m.getModifiers();if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}/** This throw gets caught in ZygoteInit.main(), which responds* by invoking the exception's run() method. This arrangement* clears up all the stack frames that were required in setting* up the process.*/return new MethodAndArgsCaller(m, argv); // 1
}

把反射得来的的 ActivityThread.main 入口返回给 ZygoteInit.main,通过 caller.run 进行调用:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller implements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try {// 调用 ActivityThread.main mMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {Throwable cause = ex.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;} else if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException(ex);}}
}

到这里,就执行到了 ActivityThread.main 方法。

第三个阶段:进入 ActivityThread.main,最终完成 Launcher.onCreate 操作

Zygote fork 出了 Launcher 进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来就从 ActivityThread.main 方法来分析 Launcher 的创建过程:

// /frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {...// 初始化 LooperLooper.prepareMainLooper();...ActivityThread thread = new ActivityThread();// 创建 Binder 通道(创建新线程)thread.attach(false, startSeq);...if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}...// 主线程开始轮训,如果退出,程序关闭Looper.loop();...
}@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {...final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}...
}

ActivityThread.attach 会一直调用 ActivityManaggerService.attachApplication 方法:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {if (thread == null) {throw new SecurityException("Invalid application interface");}synchronized (this) {// 通过 Binder 获取传入的 pid 信息int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq); // 1Binder.restoreCallingIdentity(origId);}
}
// /frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");AppBindData data = (AppBindData)msg.obj;handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;...}...
}@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {...mInstrumentation.callApplicationOnCreate(app);...
}

调度 ActivityThread.Application,并调用了 Application.onCreate 方法,如下所示:

// /frameworks/base/core/java/android/app/Instrumentation.java
public void callApplicationOnCreate(Application app) {app.onCreate();
}

继续启动进程创建之前已经加入任务栈的那个 Activity,也就是 Launcher 应用的第一个 Activity

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {...boolean badApp = false;boolean didSomething = false;// See if the top visible activity is waiting to run in this process...if (normalMode) {try {didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); // 1} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}...
}

注释 1 处的 mAtmInternalActivityTaskManagerInternal 类型的,这个方法的作用个就是启动 Launcher 应用的第一个 Activity。该方法的实现是在 ActivityTaskManagerService 中:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {synchronized (mGlobalLockWithoutBoost) {return mRootActivityContainer.attachApplication(wpc); // 1}
}

这里进一步交给了 RootActivityContainer;

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {final String processName = app.mName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {final ActivityDisplay display = mActivityDisplays.get(displayNdx);// 获取可见的/活跃的任务栈final ActivityStack stack = display.getFocusedStack();if (stack != null) {// 取出该任务栈中的所有 ActivityRecord,并存储到 mTmpActivityList 中stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);// 取出栈顶的 Activityfinal ActivityRecord top = stack.topRunningActivityLocked();final int size = mTmpActivityList.size();for (int i = 0; i < size; i++) { // 遍历任务栈中的 Activityfinal ActivityRecord activity = mTmpActivityList.get(i);if (activity.app == null && app.mUid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {if (mStackSupervisor.realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) { // 1didSomething = true; // 只有该 Activity 是在栈顶,andResume 参数才为 true}} catch (RemoteException e) {Slog.w(TAG, "Exception in new application when starting activity " + top.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisible(null, 0, false /* preserve_windows */);}return didSomething;
}

注释 1 处调用 ActivityStackSupervisor.realStartActivityLocked

// frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {...final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);final DisplayContent dc = r.getDisplay().mDisplayContent;clientTransaction.addCallback( LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, mergedConfiguration.getGlobalConfiguration(),  mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),r.icicle, r.persistentState, results, newIntents,  dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 1...
}

这里的 LauncherActivityItemResumeActivityItem 等是在 Android 10 的改动,把 Activity 的生命周期拆分成 ActivityLifecycleItem,根据不同的状态让不同的 ActivityLifecycleItem 去执行不同的 Activity 的生命周期,这种设计模式叫做状态机。状态机模式中,见过每一个条件的分支,放入一个独立的类中,去除过多的 if else 分支语句。

在注释 1 处,一旦执行了 ClientLifecycleManager.scheduleTransaction 开启了事务,就会调用到 LaunchActivityItem

class ClientLifecycleManager {void scheduleTransaction(ClientTransaction transaction) throws RemoteException {final IApplicationThread client = transaction.getClient();transaction.schedule();if (!(client instanceof Binder)) {transaction.recycle();}}
}

一旦执行了 ClientLifecycleManager.scheduleTransaction 开启事务,就会调用 LaunchActivityItem.execute 方法,然后就会调用到 ActivityClientRecord.handleLaunchActivity 方法:

// /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mIsForward,mProfilerInfo, client,mAssistToken);client.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

ClientTransactionHandlerActivityThread 的父类,是一个抽象类,所以直接去 ActivityThread 中去查看,在 ActivityThread.

// /frameworks/base/core/java/android/app/ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {...final Activity a = performLaunchActivity(r, customIntent);...
}

这个方法就会去真正的启动 Activity,并且返回一个 Activity 对象。当得到这个 Activity 的实例对象之后,

// /frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...
}

查看 Instrumentation.callActivityOnCreate 方法:

// /frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity); // Activity onCreate 预处理activity.performCreate(icicle, persistentState); // 执行 onCreatepostPerformCreate(activity); // Activity onCreate 创建后的一些信息处理
}

Instrumentation.prePerformCreate 方法:

// frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {...if (persistentState != null) {onCreate(icicle, persistentState);} else {onCreate(icicle);}...
}

同理,如果还往事务中添加了 ResumeActivityItem,相应的也会执行 Activity.onResume 生命周期。

参考

Android系统开机到Launcher启动流程分析


http://www.ppmy.cn/news/12738.html

相关文章

你是真的“C”——函数递归详解汉诺塔+青蛙跳台阶

函数递归详解汉诺塔青蛙跳台阶问题&#x1f60e;前言&#x1f64c;函数递归之汉诺塔详解分析&#x1f64c;汉诺塔问题的简介&#x1f60a;汉诺塔的移动图解&#x1f60a;汉诺塔具体的移动过程展示&#x1f60a;汉诺塔的难处所在&#xff1a;&#x1f60a;函数递归之青蛙跳台阶详…

AHOcoder声码器

AHOcoder声码器 目前最常见的声码器有WORLD&#xff0c;STRAIGHT&#xff0c;&#xff27;riffin_Lim等&#xff0c;AHocoder算是少见的&#xff0c;但也可以学习一下。 代码下载网址&#xff1a;AHOcoder 简介 AHOcoder 语音声码器由 Daniel Erro 在巴斯克大学的 AHOLAB 信…

C语言文件操作(一)

我们之前写程序&#xff0c;得到运行结果&#xff0c;退出运行&#xff0c;运行结果就不见了&#xff0c;因为运行的结果放到了内存中&#xff0c;退出程序的时候数据就会消失&#xff0c;等下一次运行又要重新输入数据&#xff0c;这样就显得很麻烦。那么我们如何保存之前的运…

鉴源论坛 · 观通丨轨交系统安全性设计

作者 | 刘艳青 上海控安安全测评中心安全测评部测试经理 版块 | 鉴源论坛 观通 引语&#xff1a;第一篇对轨交信号系统从铁路系统分类和组成、城市轨交系统分类和组成、城市轨交系统功能、城市轨交系统发展方面做了介绍&#xff0c;第二篇从信号基础出发&#xff0c;讲述了信…

MyBatis-Plus数据安全保护(加密解密)

项目创建POM依赖 <dependency><!--MyBatis-Plus 企业级模块--><groupId>com.baomidou</groupId><artifactId>mybatis-mate-starter</artifactId><version>1.2.8</version> </dependency> <!-- https://mvnrepository…

价值创造链路及经营计划

“价值创造过程最主要的环节是建立链接&#xff0c;北京万柳书院在网上热议&#xff0c;其背后是人与人的大量链接&#xff0c;近期热议的湖南卫视春晚亦如是&#xff0c;这种链接为价值的设计、沟通、传递创造条件&#xff1b;企业以客户为中心设计产品&#xff0c;往大了说是…

linux挂载新磁盘

一、查看磁盘挂载状态&#xff1a; fdisk -l df -h 二、为其中一个磁盘创建新的分区&#xff0c;参考&#xff1a; linux用fdisk创建分区,在Linux下用fdisk创建分区_weixin_39968410的博客-CSDN博客 sudo fdisk /dev/nvme0n1 1. 创建主分区&#xff1a; -----------------…

工作的同时,我也在这里做副业

文章目录一、什么是独自开&#xff1f;二、独自开能给我们带来什么利益&#xff1f;三、如何使用独自开&#xff1f;3.1、用户任务报价步骤13.2、用户任务报价步骤2四、未来的愿景一、什么是独自开&#xff1f; 独自开&#xff0c;全称独自开发一套系统&#xff0c;是基于商品…