Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程。
阅读本文大约需要花费50分钟。
文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。
相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。
文章首发微信公众号:IngresGe
专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!
欢迎关注我的公众号!
[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析
[Android取经之路] 系列文章:
《系统启动篇》
- Android系统架构
- Android是怎么启动的
- Android 10.0系统启动之init进程
- Android10.0系统启动之Zygote进程
- Android 10.0 系统启动之SystemServer进程
- Android 10.0 系统服务之ActivityMnagerService
- Android10.0系统启动之Launcher(桌面)启动流程
- Android10.0应用进程创建过程以及Zygote的fork流程
- Android 10.0 PackageManagerService(一)工作原理及启动流程
- Android 10.0 PackageManagerService(二)权限扫描
- Android 10.0 PackageManagerService(三)APK扫描
- Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》
- Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
- Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
- Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
- Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现
《Binder通信原理》:
- Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
- Android10.0 Binder通信原理(二)-Binder入门篇
- Android10.0 Binder通信原理(三)-ServiceManager篇
- Android10.0 Binder通信原理(四)-Native-C\C++实例分析
- Android10.0 Binder通信原理(五)-Binder驱动分析
- Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
- Android10.0 Binder通信原理(七)-Framework binder示例
- Android10.0 Binder通信原理(八)-Framework层分析
- Android10.0 Binder通信原理(九)-AIDL Binder示例
- Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
- Android10.0 Binder通信原理(十一)-Binder总结
《HwBinder通信原理》
- HwBinder入门篇-Android10.0 HwBinder通信原理(一)
- HIDL详解-Android10.0 HwBinder通信原理(二)
- HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
- HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
- HwServiceManager篇-Android10.0 HwBinder通信原理(五)
- Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
- Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
- JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
- JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
- HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
- HwBinder原理总结-Android10.0 HwBinder通信原理(十一)
《编译原理》
- 编译系统入门篇-Android10.0编译系统(一)
- 编译环境初始化-Android10.0编译系统(二)
- make编译过程-Android10.0编译系统(三)
- Image打包流程-Android10.0编译系统(四)
- 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的启动由三部分启动:
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()方法
源码:
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取经之路]相关推荐
- Android 10.0 PackageManagerService(一)工作原理及启动流程-[Android取经之路]
摘要:PackageManagerService是Android系统核心服务之一,在Android中的非常重要,主要负责APK.jar包等的管理. 阅读本文大约需要花费50分钟. 文章的内容主要还是从 ...
- Android 10.0 系统服务之ActivityMnagerService-AMS启动流程-[Android取经之路]
摘要:上一节我们讲完了SystemServer的启动过程,这一节接着上一节的步骤,来讲解ActivityManagerService的启动过程. ActivityManagerService简称AMS ...
- Android10.0应用进程创建过程以及Zygote的fork流程-[Android取经之路]
摘要:点击手机桌面图标,例如微信,它是如何启动的呢,让我们从系统源码级来一起分析. 阅读本文大约需要花费1小时. 文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码 ...
- Android 10.0 PackageManagerService(三)APK扫描-[Android取经之路]
摘要:上一节讲解了PKMS的 权限扫描,扫描/system/etc/permissions中的xml,存入相应的结构体中,供之后权限管理使用. 这一节主要来讲讲APK的扫描. 阅读本文大约需要花费15 ...
- Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]
摘要:PackageManagerService在systemReady()后,进行了/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,供以后使用 阅读本文大约 ...
- Android是怎么启动的-[Android取经之路]
摘要:本节主要来讲解Android是如何启动的 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! ...
- Android10.0系统启动之Zygote进程-[Android取经之路]
[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析 [Android取经之路] 系列文章: <系统启动篇> Android系统架构 Android是怎么启动的 ...
- Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现-[Android取经之路]
摘要:本节主要来讲解Android10.0 selinux.kernel日志在logd中的实现,包括LogAudit.LogKlog的源码分析 阅读本文大约需要花费15分钟. 文章首发微信公众号:In ...
- Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]
摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...
最新文章
- python文件可以用什么软件打开-py文件用什么可以打开.
- 高可用集群中的选举机制
- 《Elixir in Action》书评及作者问答录
- Zabbix 企业级监控_
- Linux wifi连接桌面,【已解决】Arch linux 安装之后在deepin桌面环境下使用networkmanager连接wifi 出现间歇性重连的情况...
- 深入理解Spark 2.1 Core (五):Standalone模式运行的原理与源码分析
- mysql mysqld.sock_MySQL笔记-最简单的方法来解决找不到mysqld.sock文件的问题
- mysql 其他引擎
- 别看程序员只是表面风光
- mybatis sql标签_【1039期】Mybatis面试18问,你想知道的都在这里了!
- Interbase浴火重生:开源数据库Firebird更新到2.12
- java Hello World程序分析(翻译自Java Tutorials)
- MVVM 实战之计算器
- 发那科机器人圆弧指令怎么用_发那科机器人走弧线的指令是什么
- 假想参考解码器 vbv HRD
- 10bit色深灰度图彩色图加载显示
- 在Mac上安装和配置Tunnelblick工具
- js实现微信表情发送
- JavaEE全套资料+视频+工具
- 车用高速音视频传输串行总线技术简介(APIX、FPD-LINK、GMSL、ClockLessLink)
热门文章
- C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配
- 电子商务中遇到组合搜索的问题
- 内核随记(三)--同步(2)【转】
- BZOJ-1644: [Usaco2007 Oct]Obstacle Course 障碍训练课(SPFA)
- SqlDataReader生成动态Lambda表达式
- nginx处理web请求分析
- 更改sybase下设备名
- 51CTO我的梦想将在这里起航【我与51CTO的故事】
- Google在中国打败百度的方法其实很简单.只要需改变5点.
- [持续交付实践] 最后一公里,你需要一套具备质量思维的发布平台!