Launcher的启动经过了三个阶段:

第一个阶段:SystemServer完成启动Launcher Activity的调用

第二个阶段:Zygote()进行Launcher进程的Fork操作

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

1. 概述

上一节我们学习了AMS\ATM的启动流程,这一节主要来学习Launcher的启动流程。

在Android的中,桌面应用Launcher由Launcher演变到Launcher2,再到现在的Launcher3,Google也做了很多改动。

Launcher不支持桌面小工具动画效果,Launcher2添加了动画效果和3D初步效果支持,从Android 4.4 (KK)开始Launcher默认使用Launcher3,    Launcher3加入了透明状态栏,增加overview模式,可以调整workspace上页面的前后顺序,可以动态管理屏幕数量,widget列表与app list分开显示等功能。

我们主要研究Launcher3的启动过程。

2.核心源码

  1. /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
  2. /frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
  3. /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
  4. /frameworks/base/core/java/com/android/internal/os/Zygote.java
  5. /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
  6. /frameworks/base/services/java/com/android/server/SystemServer.java
  7. /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
  8. /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
  9. /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
  10. /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
  11. /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
  12. /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
  13. /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
  14. /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
  15. /frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
  16. /frameworks/base/core/java/android/os/Process.java
  17. /frameworks/base/core/java/android/os/ZygoteProcess.java
  18. /frameworks/base/core/java/android/app/ActivityThread.java
  19. /frameworks/base/core/java/android/app/Activity.java
  20. /frameworks/base/core/java/android/app/ActivityManagerInternal.java
  21. /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
  22. /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
  23. /frameworks/base/core/java/android/app/ClientTransactionHandler.java
  24. /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
  25. /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
  26. /frameworks/base/core/java/android/app/Instrumentation.java
  27. /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

从上面的代码路径可以看出,Android10.0中 Activity的相关功能被放到了wm的目录中,在Android9.0中是在am目录中,Google 最终的目的是把activity 和window融合,在Android10中只是做了简单的代码路径的变更,正在的功能还要到后面的版本才能慢慢融合。

主要代码作用:

  • Instrumentation:负责调用Activity和Application生命周期。

  • ActivityTaskManagerService:负责Activity管理和调度等工作。 ATM是Android10中新增内容

  • ActivityManagerService:负责管理四大组件和进程,包括生命周期和状态切换。

  • ActivityTaskManagerInternal:是由ActivityTaskManagerService对外提供的一个抽象类,真正的实现是在 ActivityTaskManagerService#LocalService

  • ActivityThread:管理应用程序进程中主线程的执行

  • ActivityStackSupervisor:负责所有Activity栈的管理

  • TransactionExecutor:主要作用是执行ClientTransaction

  • ClientLifecycleManager:生命周期的管理调用

3.架构

Android启动流程图:

Launcher启动序列图:

内容较多,例如Zygote的fork流程,realStartActivityLocked启动Activity的中间过程,都没有列出,下一个章节会单独来讲这部分内容

4.源码分析

上一节在AMS启动过程中,我们知道了AMS启动完成前,在systemReady()中会去调用startHomeOnAllDisplays()来启动Launcher,本次就从startHomeOnAllDisplays()函数入口,来看看Launcher是如何被启动起来的。

  1. [ActivityManagerService.java]
  2. public void systemReady(final Runnable goingCallback, TimingsTraceLog
  3. traceLog) {
  4. ...
  5. //启动Home Activity
  6. mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
  7. ...
  8. }

Launcher的启动由三部分启动:

  • SystemServer完成启动Launcher Activity的调用

  • Zygote()进行Launcher进程的Fork操作

  • 进入ActivityThread的main(),完成最终Launcher的onCreate操作

接下来我们分别从源码部分来分析这三个启动过程。

4.1 第一阶段SystemServer 启动HomeActivity的调用阶段

调用栈:

[ActivityTaskManagerService.java] startHomeOnAllDisplays()

说明:ActivityTaskManagerInternal是 ActivityTaskManagerService的一个抽象类,正在的实现是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最终调用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法

源码:

  1. public boolean startHomeOnAllDisplays(int userId, String reason) {
  2. synchronized (mGlobalLock) {
  3. //一路调用到 RootActivityContainer 的startHomeOnDisplay()方法,参考[4.2]
  4. return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
  5. }
  6. }

4.2 [RootActivityContainer.java] startHomeOnDisplay()

说明:在[4.1]中,获取的displayId为DEFAULT_DISPLAY, 首先通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是Home Activity;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity

源码:

  1. boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
  2. boolean fromHomeKey) {
  3. ...
  4. if (displayId == DEFAULT_DISPLAY) {
  5. //构建一个category为CATEGORY_HOME的Intent,表明是Home Activity,参考[4.2.1]
  6. homeIntent = mService.getHomeIntent();
  7. //通过PKMS从系统所用已安装的引用中,找到一个符合HomeItent的Activity参考[4.2.2]
  8. aInfo = resolveHomeActivity(userId, homeIntent);
  9. }
  10. ...
  11. //启动Home Activity,参考[4.3]
  12. mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
  13. displayId);
  14. return true;
  15. }

4.2.1 [ActivityTaskManagerService.java] getHomeIntent()

说明:构建一个category为CATEGORY_HOME的Intent,表明是Home Activity。

Intent.CATEGORY_HOME = "android.intent.category.HOME"

这个category会在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity

源码:

  1. int execute() {
  2. ...
  3. if (mRequest.mayWait) {
  4. return startActivityMayWait(...)
  5. } else {
  6. return startActivity(...) //参考[4.3.2]
  7. }
  8. ...
  9. }

4.2.2 [RootActivityContainer.java] resolveHomeActivity()

说明: 通过Binder跨进程通知PackageManagerService从系统所用已安装的引用中,找到一个符合HomeItent的Activity

源码:

  1. ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
  2. final int flags = ActivityManagerService.STOCK_PM_FLAGS;
  3. final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为null
  4. ActivityInfo aInfo = null;
  5. ...
  6. if (comp != null) {
  7. // Factory test.
  8. aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
  9. } else {
  10. //系统正常启动时,走该流程
  11. final String resolvedType =
  12. homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
  13. //resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求Activities
  14. // 2.通过chooseBestActivity找到最符合Intent需求的Activity信息
  15. final ResolveInfo info = AppGlobals.getPackageManager()
  16. .resolveIntent(homeIntent, resolvedType, flags, userId);
  17. if (info != null) {
  18. aInfo = info.activityInfo;
  19. }
  20. }
  21. ...
  22. aInfo = new ActivityInfo(aInfo);
  23. aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
  24. return aInfo;
  25. }

4.3 [ActivityStartController.java ] startHomeActivity()

说明:正在的启动Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。另外如果home activity处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复。并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。

源码:

  1. void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
  2. ....
  3. //返回一个 ActivityStarter 对象,它负责 Activity 的启动
  4. //一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑
  5. //最后执行 ActivityStarter的execute方法
  6. mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
  7. .setOutActivity(tmpOutRecord)
  8. .setCallingUid(0)
  9. .setActivityInfo(aInfo)
  10. .setActivityOptions(options.toBundle())
  11. .execute(); //参考[4.3.1]
  12. mLastHomeActivityStartRecord = tmpOutRecord[0];
  13. final ActivityDisplay display =
  14. mService.mRootActivityContainer.getActivityDisplay(displayId);
  15. final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
  16. if (homeStack != null && homeStack.mInResumeTopActivity) {
  17. //如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复),
  18. //并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。
  19. mSupervisor.scheduleResumeTopActivities();
  20. }
  21. }

4.3.1 [ActivityStarter.java] execute()

说明: 在[4.3]中obtainStarter没有调用setMayWait的方法,因此mRequest.mayWait为false,走startActivity流程

源码:

  1. int execute() {
  2. ...
  3. if (mRequest.mayWait) {
  4. return startActivityMayWait(...)
  5. } else {
  6. return startActivity(...) //参考[4.3.2]
  7. }
  8. ...
  9. }

4.3.2 [ActivityStarter.java] startActivity()

说明: 延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局

源码:

  1. private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
  2. IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
  3. int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
  4. ActivityRecord[] outActivity, boolean restrictedBgActivity) {
  5. ...
  6. try {
  7. //延时布局
  8. mService.mWindowManager.deferSurfaceLayout();
  9. //调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities(),参考[4.3.4]
  10. result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
  11. startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
  12. } finally {
  13. //恢复布局
  14. mService.mWindowManager.continueSurfaceLayout();
  15. }
  16. ...
  17. }

4.3.3 [RootActivityContainer.java]  resumeFocusedStacksTopActivities()

说明:获取栈顶的Activity,恢复它

源码:

  1. boolean resumeFocusedStacksTopActivities(
  2. ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
  3. ...
  4. //如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()
  5. if (targetStack != null && (targetStack.isTopStackOnDisplay()
  6. || getTopDisplayFocusedStack() == targetStack)) {
  7. result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
  8. ...
  9. if (!resumedOnDisplay) {
  10. // 获取 栈顶的 ActivityRecord
  11. final ActivityStack focusedStack = display.getFocusedStack();
  12. if (focusedStack != null) {
  13. //最终调用startSpecificActivityLocked(),参考[4.3.4]
  14. focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
  15. }
  16. }
  17. }
  18. }

4.3.4 [ActivityStackSupervisor.java] startSpecificActivityLocked()

说明: 发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()

源码:

  1. void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
  2. ...
  3. //发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
  4. //最终调用到AMS的startProcess(),参考[4.3.5]
  5. final Message msg = PooledLambda.obtainMessage(
  6. ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
  7. r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
  8. mService.mH.sendMessage(msg);
  9. ...
  10. }

4.3.5 [ActivityManagerService.java] startProcess()

说明:一路调用Process start(),最终到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程

源码:

  1. public void startProcess(String processName, ApplicationInfo info,
  2. boolean knownToBeDead, String hostingType, ComponentName hostingName) {
  3. ..
  4. //同步操作,避免死锁
  5. synchronized (ActivityManagerService.this) {
  6. //调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult()
  7. //用来fork一个新的Launcher的进程,参考[4.3.6]
  8. startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
  9. new HostingRecord(hostingType, hostingName),
  10. false /* allowWhileBooting */, false /* isolated */,
  11. true /* keepIfLarge */);
  12. }
  13. ...
  14. }

调用栈如下:

4.3.6 [ZygoteProcess.java]  attemptZygoteSendArgsAndGetResult()

说明:通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法

源码:

  1. private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
  2. ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
  3. try {
  4. //传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
  5. final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
  6. final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
  7. zygoteWriter.write(msgStr); //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
  8. zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态, 参考[4.4]
  9. //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
  10. Process.ProcessStartResult result = new Process.ProcessStartResult();
  11. result.pid = zygoteInputStream.readInt();
  12. result.usingWrapper = zygoteInputStream.readBoolean();
  13. if (result.pid < 0) {
  14. throw new ZygoteStartFailedEx("fork() failed");
  15. }
  16. return result;
  17. } catch (IOException ex) {
  18. zygoteState.close();
  19. Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
  20. + ex.toString());
  21. throw new ZygoteStartFailedEx(ex);
  22. }
  23. }

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

说明:Zygote的启动过程我们前面有详细讲到过。SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。

由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

fork过程,参考下图:

Zygote的调用栈如下:

4.4.1 [ZygoteInit.java] main()

说明Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher

源码:

  1. public static void main(String argv[]) {
  2. ...
  3. Runnable caller;
  4. ....
  5. if (startSystemServer) {
  6. //Zygote Fork出的第一个进程 SystmeServer
  7. Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
  8. if (r != null) {
  9. r.run();
  10. return;
  11. }
  12. }
  13. ...
  14. //循环等待fork出其他的应用进程,比如Launcher
  15. //最终通过调用processOneCommand()来进行进程的处理,参考[4.4.2]
  16. caller = zygoteServer.runSelectLoop(abiList);
  17. ...
  18. if (caller != null) {
  19. caller.run(); //执行返回的Runnable对象,进入子进程
  20. }
  21. }

4.4.2 [ZygoteConnection.java] processOneCommand()

说明通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理

源码:

  1. Runnable processOneCommand(ZygoteServer zygoteServer) {
  2. int pid = -1;
  3. ...
  4. //Fork子进程,得到一个新的pid
  5. /fork子进程,采用copy on write方式,这里执行一次,会返回两次
  6. ///pid=0 表示Zygote fork子进程成功
  7. //pid > 0 表示子进程 的真正的PID
  8. pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
  9. parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
  10. parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
  11. parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
  12. ...
  13. if (pid == 0) {
  14. // in child, fork成功,第一次返回的pid = 0
  15. ...
  16. //参考[4.4.3]
  17. return handleChildProc(parsedArgs, descriptors, childPipeFd,
  18. parsedArgs.mStartChildZygote);
  19. } else {
  20. //in parent
  21. ...
  22. childPipeFd = null;
  23. handleParentProc(pid, descriptors, serverPipeFd);
  24. return null;
  25. }
  26. }

4.4.3 [ZygoteConnection.java] handleChildProc()

说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()

源码:

  1. private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
  2. FileDescriptor pipeFd, boolean isZygote) {
  3. ...
  4. if (parsedArgs.mInvokeWith != null) {
  5. ...
  6. throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
  7. } else {
  8. if (!isZygote) {
  9. // App进程将会调用到这里,执行目标类的main()方法
  10. return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
  11. parsedArgs.mRemainingArgs, null /* classLoader */);
  12. } else {
  13. return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
  14. parsedArgs.mRemainingArgs, null /* classLoader */);
  15. }
  16. }
  17. }

zygoteInit 进行一些环境的初始化、启动Binder进程等操作:

  1. public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
  2. ClassLoader classLoader) {
  3. RuntimeInit.commonInit(); //初始化运行环境
  4. ZygoteInit.nativeZygoteInit(); //启动Binder线程池
  5. //调用程序入口函数
  6. return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
  7. }

把之前传来的"android.app.ActivityThread" 传递给findStaticMain:

  1. protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
  2. ClassLoader classLoader) {
  3. ...
  4. // startClass: 如果AMS通过socket传递过来的是 ActivityThread
  5. return findStaticMain(args.startClass, args.startArgs, classLoader);
  6. }

把之前传来的"android.app.ActivityThread" 传递给findStaticMain:

  1. protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
  2. ClassLoader classLoader) {
  3. ...
  4. // startClass: 如果AMS通过socket传递过来的是 ActivityThread
  5. return findStaticMain(args.startClass, args.startArgs, classLoader);
  6. }

通过反射,拿到ActivityThread的main()方法:

  1. protected static Runnable findStaticMain(String className, String[] argv,
  2. ClassLoader classLoader) {
  3. Class<?> cl;
  4. try {
  5. cl = Class.forName(className, true, classLoader);
  6. } catch (ClassNotFoundException ex) {
  7. throw new RuntimeException(
  8. "Missing class when invoking static main " + className,
  9. ex);
  10. }
  11. Method m;
  12. try {
  13. m = cl.getMethod("main", new Class[] { String[].class });
  14. } catch (NoSuchMethodException ex) {
  15. throw new RuntimeException(
  16. "Missing static main on " + className, ex);
  17. } catch (SecurityException ex) {
  18. throw new RuntimeException(
  19. "Problem getting static main on " + className, ex);
  20. }
  21. int modifiers = m.getModifiers();
  22. if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
  23. throw new RuntimeException(
  24. "Main method is not public and static on " + className);
  25. }
  26. return new MethodAndArgsCaller(m, argv);
  27. }

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

  1. static class MethodAndArgsCaller implements Runnable {
  2. /** method to call */
  3. private final Method mMethod;
  4. /** argument array */
  5. private final String[] mArgs;
  6. public MethodAndArgsCaller(Method method, String[] args) {
  7. mMethod = method;
  8. mArgs = args;
  9. }
  10. //调用ActivityThread的main()
  11. public void run() {
  12. try {
  13. mMethod.invoke(null, new Object[] { mArgs });
  14. } catch (IllegalAccessException ex) {
  15. throw new RuntimeException(ex);
  16. } catch (InvocationTargetException ex) {
  17. Throwable cause = ex.getCause();
  18. if (cause instanceof RuntimeException) {
  19. throw (RuntimeException) cause;
  20. } else if (cause instanceof Error) {
  21. throw (Error) cause;
  22. }
  23. throw new RuntimeException(ex);
  24. }
  25. }
  26. }

4.5 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作

从[4.4]可以看到,Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来我们就从ActivityThread main()来分析Launcher的创建过程。

调用栈如下:

4.5.1 [ActivityThread.java] main()

说明主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环

源码:

  1. p}ublic static void main(String[] args) {
  2. // 安装选择性的系统调用拦截
  3. AndroidOs.install();
  4. ...
  5. //主线程处理
  6. Looper.prepareMainLooper();
  7. ...
  8. //之前SystemServer调用attach传入的是true,这里到应用进程传入false就行
  9. ActivityThread thread = new ActivityThread();
  10. thread.attach(false, startSeq);
  11. ...
  12. //一直循环,如果退出,说明程序关闭
  13. Looper.loop();
  14. throw new RuntimeException("Main thread loop unexpectedly exited");
  15. }

调用ActivityThread的attach进行处理

  1. private void attach(boolean system, long startSeq) {
  2. sCurrentActivityThread = this;
  3. mSystemThread = system;
  4. if (!system) {
  5. //应用进程启动,走该流程
  6. ...
  7. RuntimeInit.setApplicationObject(mAppThread.asBinder());
  8. //获取AMS的本地代理类
  9. final IActivityManager mgr = ActivityManager.getService();
  10. try {
  11. //通过Binder调用AMS的attachApplication方法,参考[4.5.2]
  12. mgr.attachApplication(mAppThread, startSeq);
  13. } catch (RemoteException ex) {
  14. throw ex.rethrowFromSystemServer();
  15. }
  16. ...
  17. } else {
  18. //通过system_server启动ActivityThread对象
  19. ...
  20. }
  21. // 为 ViewRootImpl 设置配置更新回调,
  22. 当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
  23. ViewRootImpl.ConfigChangedCallback configChangedCallback
  24. = (Configuration globalConfig) -> {
  25. synchronized (mResourcesManager) {
  26. ...
  27. }
  28. };
  29. ViewRootImpl.addConfigCallback(configChangedCallback);
  30. }

4.5.2 [ActivityManagerService.java] attachApplication()

说明:清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动

源码:

  1. public final void attachApplication(IApplicationThread thread, long startSeq) {
  2. synchronized (this) {
  3. //通过Binder获取传入的pid信息
  4. int callingPid = Binder.getCallingPid();
  5. final int callingUid = Binder.getCallingUid();
  6. final long origId = Binder.clearCallingIdentity();
  7. attachApplicationLocked(thread, callingPid, callingUid, startSeq);
  8. Binder.restoreCallingIdentity(origId);
  9. }
  10. }
  11. private final boolean attachApplicationLocked(IApplicationThread thread,
  12. int pid, int callingUid, long startSeq) {
  13. ...
  14. //如果当前的Application记录仍然依附到之前的进程中,则清理掉
  15. if (app.thread != null) {
  16. handleAppDiedLocked(app, true, true);
  17. //mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
  18. //所以这里的normalMode也为true
  19. boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
  20. ...
  21. //上面说到,这里为true,进入StackSupervisor的attachApplication方法
  22. //去真正启动Activity
  23. if (normalMode) {
  24. ...
  25. //调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
  26. //参考[4.5.3]
  27. didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
  28. ...
  29. }
  30. ...
  31. return true;
  32. }

4.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()

说明:真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用

ClientLifecycleManager.scheduleTransaction()得到

LaunchActivityItem的execute()方法进行最终的执行 参考上面的第三阶段的调用栈流程 调用栈如下:

  1. boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
  2. boolean andResume, boolean checkConfig) throws RemoteException {
  3. // 直到所有的 onPause() 执行结束才会去启动新的 activity
  4. if (!mRootActivityContainer.allPausedActivitiesComplete()) {
  5. ...
  6. return false;
  7. }
  8. try {
  9. // Create activity launch transaction.
  10. // 添加 LaunchActivityItem
  11. final ClientTransaction clientTransaction = ClientTransaction.obtain(
  12. proc.getThread(), r.appToken);
  13. //LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
  14. clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
  15. System.identityHashCode(r), r.info,
  16. // TODO: Have this take the merged configuration instead of separate global
  17. // and override configs.
  18. mergedConfiguration.getGlobalConfiguration(),
  19. mergedConfiguration.getOverrideConfiguration(), r.compat,
  20. r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
  21. r.icicle, r.persistentState, results, newIntents,
  22. dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
  23. r.assistToken));
  24. ...
  25. // 设置生命周期状态
  26. final ActivityLifecycleItem lifecycleItem;
  27. if (andResume) {
  28. lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
  29. } else {
  30. lifecycleItem = PauseActivityItem.obtain();
  31. }
  32. clientTransaction.setLifecycleStateRequest(lifecycleItem);
  33. // Schedule transaction.
  34. // 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
  35. //参考[4.5.4]
  36. mService.getLifecycleManager().scheduleTransaction(clientTransaction);
  37. } catch (RemoteException e) {
  38. if (r.launchFailed) {
  39. // 第二次启动失败,finish activity
  40. stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
  41. "2nd-crash", false);
  42. return false;
  43. }
  44. // 第一次失败,重启进程并重试
  45. r.launchFailed = true;
  46. proc.removeActivity(r);
  47. throw e;
  48. }
  49. } finally {
  50. endDeferResume();
  51. }
  52. ...
  53. return true;
  54. }

4.5.4 [TransactionExecutor.java] execute()

说明:执行之前realStartActivityLocked()中的clientTransaction.addCallback

clientTransaction.addCallback

源码:

  1. [TransactionExecutor.java]
  2. public void execute(ClientTransaction transaction) {
  3. ...
  4. // 执行 callBack,参考上面的调用栈,执行回调方法,
  5. //最终调用到ActivityThread的handleLaunchActivity()参考[4.5.5]
  6. executeCallbacks(transaction);
  7. // 执行生命周期状态
  8. executeLifecycleState(transaction);
  9. mPendingActions.clear();
  10. }

4.5.5 [ActivityThread.java]  handleLaunchActivity()

说明主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法

源码:

  1. [ActivityThread.java]
  2. public Activity handleLaunchActivity(ActivityClientRecord r,
  3. PendingTransactionActions pendingActions, Intent customIntent) {
  4. ...
  5. //初始化WindowManagerGlobal
  6. WindowManagerGlobal.initialize();
  7. ...
  8. //调用performLaunchActivity,来处理Activity,参考[4.5.6]
  9. final Activity a = performLaunchActivity(r, customIntent);
  10. ..
  11. return a;
  12. }

4.5.6 [ActivityThread.java] performLaunchActivity()

说明:获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等; 最终调用callActivityOnCreate()来执行Activity的onCreate()方法

源码

  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  2. // 获取 ComponentName
  3. ComponentName component = r.intent.getComponent();
  4. ...
  5. // 获取 Context
  6. ContextImpl appContext = createBaseContextForActivity(r);
  7. Activity activity = null;
  8. try {
  9. // 反射创建 Activity
  10. java.lang.ClassLoader cl = appContext.getClassLoader();
  11. activity = mInstrumentation.newActivity(
  12. cl, component.getClassName(), r.intent);
  13. StrictMode.incrementExpectedActivityCount(activity.getClass());
  14. r.intent.setExtrasClassLoader(cl);
  15. r.intent.prepareToEnterProcess();
  16. if (r.state != null) {
  17. r.state.setClassLoader(cl);
  18. }
  19. } catch (Exception e) {
  20. ...
  21. }
  22. try {
  23. // 获取 Application
  24. Application app = r.packageInfo.makeApplication(false, mInstrumentation);
  25. if (activity != null) {
  26. ...
  27. //Activity的一些处理
  28. activity.attach(appContext, this, getInstrumentation(), r.token,
  29. r.ident, app, r.intent, r.activityInfo, title, r.parent,
  30. r.embeddedID, r.lastNonConfigurationInstances, config,
  31. r.referrer, r.voiceInteractor, window, r.configCallback,
  32. r.assistToken);
  33. if (customIntent != null) {
  34. activity.mIntent = customIntent;
  35. }
  36. ...
  37. int theme = r.activityInfo.getThemeResource();
  38. if (theme != 0) {
  39. // 设置主题
  40. activity.setTheme(theme);
  41. }
  42. activity.mCalled = false;
  43. // 执行 onCreate()
  44. if (r.isPersistable()) {
  45. mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
  46. } else {
  47. mInstrumentation.callActivityOnCreate(activity, r.state);
  48. }
  49. ...
  50. r.activity = activity;
  51. }
  52. //当前状态为ON_CREATE
  53. r.setState(ON_CREATE);
  54. ...
  55. } catch (SuperNotCalledException e) {
  56. throw e;
  57. } catch (Exception e) {
  58. ...
  59. }
  60. return activity;
  61. }

callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理

  1. public void callActivityOnCreate(Activity activity, Bundle icicle,
  2. PersistableBundle persistentState) {
  3. prePerformCreate(activity); //activity onCreate的预处理
  4. activity.performCreate(icicle, persistentState);//执行onCreate()
  5. postPerformCreate(activity); //activity onCreate创建后的一些信息处理
  6. }
  7. public void callActivityOnCreate(Activity activity, Bundle icicle,
  8. PersistableBundle persistentState) {
  9. prePerformCreate(activity); //activity onCreate的预处理
  10. activity.performCreate(icicle, persistentState);//执行onCreate()
  11. postPerformCreate(activity); //activity onCreate创建后的一些信息处理
  12. }

performCreate()主要调用Activity的onCreate()

  1. final void performCreate(Bundle icicle, PersistableBundle persistentState) {
  2. ...
  3. if (persistentState != null) {
  4. onCreate(icicle, persistentState);
  5. } else {
  6. onCreate(icicle);
  7. }
  8. ...
  9. }

至此,看到了我们最熟悉的Activity的onCreate(),Launcher的启动完成,Launcher被真正创建起来。

5.总结

看到onCreate()后,进入到我们最熟悉的Activity的入口,Launcher的启动告一段落。整个Android的启动流程,我们也完整的分析完成。

Launcher的启动经过了三个阶段:

第一个阶段:SystemServer完成启动Launcher Activity的调用

第二个阶段:Zygote()进行Launcher进程的Fork操作

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

Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]的更多相关文章

  1. 从0移植uboot (二) _启动流程分析

    经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,其次,此时的uboot.bin也没有结合 ...

  2. 从0移植uboot (二) _uboot启动流程分析

    经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,同时,此时的uboot.bin也没有结合 ...

  3. (转)从0移植uboot (二) _uboot启动流程分析

    ref:https://www.cnblogs.com/xiaojiang1025/p/6496704.html 经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够 ...

  4. Android的Launcher启动流程 “Launcher部分启动流程”

    研究代码从:AndroidManifest.xml.自定义的Application.java开始. Android系统启动时,系统需要一个Home应用程序来负责将这些应用程序展示出来:也就是该应用的目 ...

  5. Android系统开机启动流程及init进程浅析

    Android系统启动概述 Android系统开机流程基于Linux系统,总体可分为三个阶段: Boot Loader引导程序启动Linux内核启动Android系统启动,Launcher/app启动 ...

  6. 《转》深入理解Activity启动流程(四)–Activity Task的调度算法

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  7. 深入理解Activity启动流程(四)–Activity Task的调度算法

    本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启动的概要流程 深入理解Activity启动流程(二)- ...

  8. Android的开机启动流程

    1.Android的开机启动流程 Android的层次框架图,如下所示: 图片清晰地展示了Android的五层架构,从上到下依次是:应用层.应用框架层.库层.运行时层以及Linux内核层.Androi ...

  9. activiti学习6:启动流程后动态获取流程图

    目录 activiti学习6:启动流程后动态获取流程图 一.绘图原理 二.根据流程定义id绘图 三.根据流程实例id绘图 3.1 基本原理 3.2 当前节点的获取 3.3 走过的节点的获取 3.4 绘 ...

  10. Android4.0源码Launcher启动流程分析【android源码Launcher系列一】

    最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程. Launcher其实是贯彻于手机的整个系统的,时时刻刻都 ...

随机推荐

  1. 【教程】运行所选代码生成器时出错:“无法解析依赖项。"EntityFramework 6.4.4" 与 ' EntityFramework.zh-Hans 6.2.0 约束:EntityFramework(=6.2.0)'不兼容。"

    添加包含视图的控制器 执行以上添加"包含视图的MVC5控制器(使用Entity Framework)时报错 解决方案 在解决方案资源管理器中找到packages.config 注释掉Enti ...

  2. vue中的<script setup>与<script>

    <script setup>是在vue3.2之后新增的语法糖,简化了API的写法 1.声明的变量无需return,可以直接在模板中使用,实现了顶层的绑定 2.引入组件会自动注册,无需再使用 ...

  3. 解决cnpm syscall: ‘rename‘

    1.删了cnpm npm uninstall -g cnpm 2.指定版本下载cnpm npm install cnpm@7.1.0 -g

  4. 是否可以在线创建ios证书

    生成苹果证书,假如使用官方的教程去生成,非常麻烦,因为它需要使用苹果mac电脑去生成,而且生成的流程还要对苹果电脑的证书导入和导出比较熟. 因此,生成苹果ios证书,不建议使用官方的方法去生成,少走弯 ...

  5. 【Binary】XShell6 无法使用的解决办法

    感谢博主的解决方案: https://www.cnblogs.com/pinkpolk/articles/13554445.html 首先需要安装VsCode,并且安装一个[Hex Editor]的插 ...

  6. 《Python数据可视化之matplotlib实践》 源码 第四篇 扩展 第十二章

    图  12.1 import matplotlib.pyplot as plt import numpy as np barSlices=12 theta=np.linspace(0.0, 2*np. ...

  7. aarch64架构CPU下Ubuntu系统环境源码编译pytorch-gpu-2.0.1版本

    准备事项: 1. pytorch源码下载: 源码的官方地址: https://github.com/pytorch/pytorch 但是这里我们不能简单的使用git clone命令下载,因为pytor ...

  8. (计算机类)人工智能方向会议的截止时间表 —— AI Conference Deadlines —— 会议投稿截止时间

    由 https://paperswithcode.com/ 提供的时间表. 做AI方向的research,经常需要关注的就是conference的deadline,之前往往都是需要手动的去挨个搜索,下 ...

  9. 高校教编程是否应该将Python作为主语言

    偶读一文:https://www.cnblogs.com/qing-gee/p/12941219.html 想到了这样的一个老问题,个人搞计算机软件开发.人工智能的时间已经十余年,虽然个人能力有限但是 ...

  10. conda 安装pytorch

    配置:win 10 ,python=3.6 安装pytorch-1.1.0,cudatoolkit-9.0,torchvision-0.3.0. 出现的问题:import torch 的时候,出现了O ...