1 Launcher
概述
系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 Launcher
。Launcher
在启动过程中会请求 PackageManagerService
返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。
通俗的讲,Launcher
就是 Android
系统的桌面, 它的作用主要有以下两点:
- 作为
Android
系统的启动器,用于启动应用程序; - 作为
Android
系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件;
2 Launcher
启动过程
SystemServer
进程在启动的过程中会启动 PackageManagerService
,PackageManagerService
启动后会将系统中的应用程序安装完成,在此之前已经启动的 ActivityManagerService
会将 Launcher
启动起来。
Launcher
的启动分为三个部分:
SystemServer
完成启动Launcher
的Activity
的相关配置;Zygote
进程fork
出Launcher
进程;- 进入
ActivityThread.main
函数,最终完成Launcher
的onCreate
操作;
第一阶段 完成 Launcher
的相关配置
在 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...
}
这里的 mAtmInternal
是 ActivityTaskManagerInternal
的实例,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()
方法来构建一个 category
为 CATEGORY_HOME
的 Intent
,表明是一个符合 Launcher
应用的 Intent
。在注释 3
处通过调用 resolveHomeActivity
方法解析出需要启动 Activity
的信息。在注释 4
处调用 ActivityTaskManagerService.getActivityStartController()
获取 ActivityStartController
,这个类的作用就是做启动前的各项检查,比如,Activity
是否有清单文件注册,Class
文件是否存在等,之后启动 Activity
。
以下是相关的时序图:
首先,看一下 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
从系统所有已经安装的应用中找到一个符合 homeInent
的 Activity
。
再看 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()
方法是根据 Activity
的 launcher mode
和 intent.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();}...
}
Zygote
先 fork
出 system_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.forkAndSpecialize
来 fork
出 Launcher
进程,并执行 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
处的 mAtmInternal
是 ActivityTaskManagerInternal
类型的,这个方法的作用个就是启动 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...
}
这里的 LauncherActivityItem
,ResumeActivityItem
等是在 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);
}
ClientTransactionHandler
是 ActivityThread
的父类,是一个抽象类,所以直接去 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启动流程分析