摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程。

阅读本文大约需要花费50分钟。

文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。

相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。

文章首发微信公众号:IngresGe

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

欢迎关注我的公众号!

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程创建过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入门篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通信原理(五)-Binder驱动分析
  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework层分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
  11. Android10.0 Binder通信原理(十一)-Binder总结

  《HwBinder通信原理》

  1. HwBinder入门篇-Android10.0 HwBinder通信原理(一)
  2. HIDL详解-Android10.0 HwBinder通信原理(二)
  3. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
  5. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
  6. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
  7. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
  8. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
  9. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
  10. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
  11. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

《编译原理》

  1. 编译系统入门篇-Android10.0编译系统(一)
  2. 编译环境初始化-Android10.0编译系统(二)
  3. make编译过程-Android10.0编译系统(三)
  4. Image打包流程-Android10.0编译系统(四)
  5. Kati详解-Android10.0编译系统(五)

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.核心源码

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/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是如何被启动起来的。

[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {...//启动Home ActivitymAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");...
}

Launcher的启动由三部分启动:

  1. SystemServer完成启动Launcher Activity的调用

  2. Zygote()进行Launcher进程的Fork操作

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

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

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

调用栈:

[ActivityTaskManagerService.java] startHomeOnAllDisplays()

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

源码:

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

4.2 [RootActivityContainer.java] startHomeOnDisplay()

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

源码:

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

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

源码:

Intent getHomeIntent() {Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);//不是生产模式,add一个CATEGORY_HOMEif (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {intent.addCategory(Intent.CATEGORY_HOME);}return intent;
}

4.2.2 [RootActivityContainer.java] resolveHomeActivity()

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

源码:

ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {final int flags = ActivityManagerService.STOCK_PM_FLAGS;final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为nullActivityInfo aInfo = null;...if (comp != null) {// Factory test.aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);} else {//系统正常启动时,走该流程final String resolvedType =homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());//resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求Activities//            2.通过chooseBestActivity找到最符合Intent需求的Activity信息final ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(homeIntent, resolvedType, flags, userId);if (info != null) {aInfo = info.activityInfo;}}...aInfo = new ActivityInfo(aInfo);aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);return aInfo;
}

4.3 [ActivityStartController.java ] startHomeActivity()

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

源码:

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

4.3.1 [ActivityStarter.java] execute()

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

源码:

int execute() {...if (mRequest.mayWait) {return startActivityMayWait(...)} else {return startActivity(...) //参考[4.3.2]}...
}

4.3.2 [ActivityStarter.java] startActivity()

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

源码:

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {...try {//延时布局mService.mWindowManager.deferSurfaceLayout();//调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities(),参考[4.3.4]result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);} finally {//恢复布局mService.mWindowManager.continueSurfaceLayout();}...
}

4.3.3 [RootActivityContainer.java]  resumeFocusedStacksTopActivities()

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

源码:

boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {...//如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()if (targetStack != null && (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() == targetStack)) {result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);...if (!resumedOnDisplay) {// 获取  栈顶的 ActivityRecordfinal ActivityStack focusedStack = display.getFocusedStack();if (focusedStack != null) {//最终调用startSpecificActivityLocked(),参考[4.3.4]focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}
}

4.3.4 [ActivityStackSupervisor.java]  startSpecificActivityLocked()

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

源码:

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

4.3.5 [ActivityManagerService.java] startProcess()

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

源码:

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

调用栈如下:

4.3.6 [ZygoteProcess.java]  attemptZygoteSendArgsAndGetResult()

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

源码:

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

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

源码:

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

4.4.2 [ZygoteConnection.java] processOneCommand()

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

源码:

Runnable processOneCommand(ZygoteServer zygoteServer) {int pid = -1;...//Fork子进程,得到一个新的pid/fork子进程,采用copy on write方式,这里执行一次,会返回两次///pid=0 表示Zygote  fork子进程成功//pid > 0 表示子进程 的真正的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);...if (pid == 0) {// in child, fork成功,第一次返回的pid = 0...//参考[4.4.3]return handleChildProc(parsedArgs, descriptors, childPipeFd,parsedArgs.mStartChildZygote);} else {//in parent...childPipeFd = null;handleParentProc(pid, descriptors, serverPipeFd);return null;}
}

4.4.3 [ZygoteConnection.java] handleChildProc()

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

源码:

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd, boolean isZygote) {...if (parsedArgs.mInvokeWith != null) {...throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");} else {if (!isZygote) {// App进程将会调用到这里,执行目标类的main()方法return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);} else {return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);}}
}

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

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

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

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

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

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);}return new MethodAndArgsCaller(m, argv);
}

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


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;}//调用ActivityThread的main()public void run() {try {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);}}
}

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

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

调用栈如下:

4.5.1 [ActivityThread.java] main()

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

源码:

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

调用ActivityThread的attach进行处理

private void attach(boolean system, long startSeq) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {//应用进程启动,走该流程...RuntimeInit.setApplicationObject(mAppThread.asBinder());//获取AMS的本地代理类final IActivityManager mgr = ActivityManager.getService();try {//通过Binder调用AMS的attachApplication方法,参考[4.5.2]mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}...} else {//通过system_server启动ActivityThread对象...}// 为 ViewRootImpl 设置配置更新回调,当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化ViewRootImpl.ConfigChangedCallback configChangedCallback= (Configuration globalConfig) -> {synchronized (mResourcesManager) {...}};ViewRootImpl.addConfigCallback(configChangedCallback);
}

4.5.2  [ActivityManagerService.java]  attachApplication()

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

源码:

public final void attachApplication(IApplicationThread thread, long startSeq) {synchronized (this) {//通过Binder获取传入的pid信息int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq);Binder.restoreCallingIdentity(origId);}
}
private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {...//如果当前的Application记录仍然依附到之前的进程中,则清理掉if (app.thread != null) {handleAppDiedLocked(app, true, true);}·//mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,//所以这里的normalMode也为trueboolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);...//上面说到,这里为true,进入StackSupervisor的attachApplication方法//去真正启动Activityif (normalMode) {...//调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()//参考[4.5.3]didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());...}...return true;
}

4.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()

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

ClientLifecycleManager.scheduleTransaction()得到

LaunchActivityItem的execute()方法进行最终的执行

参考上面的第三阶段的调用栈流程

调用栈如下:

源码:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {// 直到所有的 onPause() 执行结束才会去启动新的 activityif (!mRootActivityContainer.allPausedActivitiesComplete()) {...return false;}try {// Create activity launch transaction.// 添加 LaunchActivityItemfinal ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);//LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,// TODO: Have this take the merged configuration instead of separate global// and override configs.mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),r.icicle, r.persistentState, results, newIntents,dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));...// 设置生命周期状态final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.// 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法//参考[4.5.4]mService.getLifecycleManager().scheduleTransaction(clientTransaction);} catch (RemoteException e) {if (r.launchFailed) {// 第二次启动失败,finish activitystack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,"2nd-crash", false);return false;}// 第一次失败,重启进程并重试r.launchFailed = true;proc.removeActivity(r);throw e;}} finally {endDeferResume();}...return true;
}

4.5.4 [TransactionExecutor.java] execute()

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

clientTransaction.addCallback

源码:

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

4.5.5 [ActivityThread.java]  handleLaunchActivity()

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

源码:

[ActivityThread.java]
public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {...//初始化WindowManagerGlobalWindowManagerGlobal.initialize();...//调用performLaunchActivity,来处理Activity,参考[4.5.6]final Activity a = performLaunchActivity(r, customIntent);..return a;
}

4.5.6 [ActivityThread.java] performLaunchActivity()

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

源码:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// 获取 ComponentNameComponentName component = r.intent.getComponent();...// 获取 ContextContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {// 反射创建 Activityjava.lang.ClassLoader cl = appContext.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state != null) {r.state.setClassLoader(cl);}} catch (Exception e) {...}try {// 获取 ApplicationApplication app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {...//Activity的一些处理activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback,r.assistToken);if (customIntent != null) {activity.mIntent = customIntent;}...int theme = r.activityInfo.getThemeResource();if (theme != 0) {// 设置主题activity.setTheme(theme);}activity.mCalled = false;// 执行 onCreate()if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...r.activity = activity;}//当前状态为ON_CREATEr.setState(ON_CREATE);...} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {...}return activity;
}

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

public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity); //activity onCreate的预处理activity.performCreate(icicle, persistentState);//执行onCreate()postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}

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

final void performCreate(Bundle icicle, PersistableBundle persistentState) {...if (persistentState != null) {onCreate(icicle, persistentState);} else {onCreate(icicle);}...
}

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

5.总结

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

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

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

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

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

下一节会来分析一下Android的进程创建过程以及Zygote的fork流程。

微信公众号:IngresGe

Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]相关推荐

  1. Android 10.0 PackageManagerService(一)工作原理及启动流程-[Android取经之路]

    摘要:PackageManagerService是Android系统核心服务之一,在Android中的非常重要,主要负责APK.jar包等的管理. 阅读本文大约需要花费50分钟. 文章的内容主要还是从 ...

  2. Android 10.0 系统服务之ActivityMnagerService-AMS启动流程-[Android取经之路]

    摘要:上一节我们讲完了SystemServer的启动过程,这一节接着上一节的步骤,来讲解ActivityManagerService的启动过程. ActivityManagerService简称AMS ...

  3. Android10.0应用进程创建过程以及Zygote的fork流程-[Android取经之路]

    摘要:点击手机桌面图标,例如微信,它是如何启动的呢,让我们从系统源码级来一起分析. 阅读本文大约需要花费1小时. 文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码 ...

  4. Android 10.0 PackageManagerService(三)APK扫描-[Android取经之路]

    摘要:上一节讲解了PKMS的 权限扫描,扫描/system/etc/permissions中的xml,存入相应的结构体中,供之后权限管理使用. 这一节主要来讲讲APK的扫描. 阅读本文大约需要花费15 ...

  5. Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]

    摘要:PackageManagerService在systemReady()后,进行了/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,供以后使用 阅读本文大约 ...

  6. Android是怎么启动的-[Android取经之路]

    摘要:本节主要来讲解Android是如何启动的 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! ...

  7. Android10.0系统启动之Zygote进程-[Android取经之路]

    [Android取经之路] 的源码都基于Android-Q(10.0) 进行分析 [Android取经之路] 系列文章: <系统启动篇> Android系统架构 Android是怎么启动的 ...

  8. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​-[Android取经之路]

    摘要:本节主要来讲解Android10.0 selinux.kernel日志在logd中的实现,包括LogAudit.LogKlog的源码分析 阅读本文大约需要花费15分钟. 文章首发微信公众号:In ...

  9. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

最新文章

  1. python文件可以用什么软件打开-py文件用什么可以打开.
  2. 高可用集群中的选举机制
  3. 《Elixir in Action》书评及作者问答录
  4. Zabbix 企业级监控_
  5. Linux wifi连接桌面,【已解决】Arch linux 安装之后在deepin桌面环境下使用networkmanager连接wifi 出现间歇性重连的情况...
  6. 深入理解Spark 2.1 Core (五):Standalone模式运行的原理与源码分析
  7. mysql mysqld.sock_MySQL笔记-最简单的方法来解决找不到mysqld.sock文件的问题
  8. mysql 其他引擎
  9. 别看程序员只是表面风光
  10. mybatis sql标签_【1039期】Mybatis面试18问,你想知道的都在这里了!
  11. Interbase浴火重生:开源数据库Firebird更新到2.12
  12. java Hello World程序分析(翻译自Java Tutorials)
  13. MVVM 实战之计算器
  14. 发那科机器人圆弧指令怎么用_发那科机器人走弧线的指令是什么
  15. 假想参考解码器 vbv HRD
  16. 10bit色深灰度图彩色图加载显示
  17. 在Mac上安装和配置Tunnelblick工具
  18. js实现微信表情发送
  19. JavaEE全套资料+视频+工具
  20. 车用高速音视频传输串行总线技术简介(APIX、FPD-LINK、GMSL、ClockLessLink)

热门文章

  1. C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配
  2. 电子商务中遇到组合搜索的问题
  3. 内核随记(三)--同步(2)【转】
  4. BZOJ-1644: [Usaco2007 Oct]Obstacle Course 障碍训练课(SPFA)
  5. SqlDataReader生成动态Lambda表达式
  6. nginx处理web请求分析
  7. 更改sybase下设备名
  8. 51CTO我的梦想将在这里起航【我与51CTO的故事】
  9. Google在中国打败百度的方法其实很简单.只要需改变5点.
  10. [持续交付实践] 最后一公里,你需要一套具备质量思维的发布平台!