本文基于Android10.0的源码。
由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的。

常见基础问题:

SystemServer系统服务进程是如何创建的?Launcher进程如何被创建的?
是由Zygote进程fork而来

Launcher启动入口在哪儿?
ActivityManagerService的systemReady函数就是启动Launcher的入口。

系统如何识别Launcher应用?
android.intent.category.HOME

如何开发一个桌面Launcher应用?
android.intent.category.HOME;
android.intent.category.DEFAUlT。

Android应用进程的的入口类?
ActivityThread

为什么Activity必须在清单文件中注册?
ActivityStarter会做各种启动前检查。

一、Android系统架构及开机流程

Google官方提供的经典分层架构图:

从下往上依次分为5层:

  • Linux内核层
  • HAL层(硬件抽象层)
  • 系统运行库层(系统Native库和Android运行时环境)
  • FramWork层(Java框架层)
  • Application层(包括Systema Apps和三方App)

Google提供的5层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌,阐述Android内部的环环相扣的内在联系。如下为:系统启动架构图

首先,关于Android手机开机的过程,Loader层:

Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设代码开始执行,然后加载引导程序到RAM;
Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数,拉起Android OS。

图解: Android系统启动过程由上图从下往上的一个过程是由Boot Loader引导开机,然后依次进入 -> Linux Kernel -> Native -> Framework -> App,接来下简要说说每个过程:

Linux内核层

Android平台的基础是Linux内核,比如ART虚拟机最终调用底层Linux内核来执行功能。Linux内核的安全机制为Android提供相应的保障,也允许设备制造商为内核开发硬件驱动程序。

启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。

硬件抽象层 (HAL)

硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。

系统运行库层

每个应用都在其自己的进程中运行,都有自己的虚拟机实例。ART通过执行DEX文件可在设备运行多个虚拟机,DEX文件是一种专为Android设计的字节码格式文件,经过优化,使用内存很少。ART主要功能包括:预先(AOT)和即时(JIT)编译,优化的垃圾回收(GC),以及调试相关的支持。

这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程init进程是所有用户进程的鼻祖

Framework层:

Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:

加载ZygoteInit类,注册Zygote Socket服务端套接字
加载虚拟机
提前加载类preloadClasses
提前加载资源preloadResouces

SystemServer系统服务进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务。

Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。

Application层

Zygote进程孵化出的第一个App进程是Launcher这是用户看到的桌面App
Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
所有的App进程都是由Zygote进程fork生成的。

二、Android系统中极其重要的进程:

init进程, Zygote进程, SystemServer进程, ServiceManager进程。

2.1.init进程

Init进程是Android启动的第一个进程,进程号为1(pid=1),是Android 的系统启动的核心进程,主要用来创建Zygote、属性服务等。 init.cpp 中的main 函数,是init进程的入口函数,源码主要存在\system\core\init目录下。

重点:它是Linux系统中用户空间的第一个进程,由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程。

init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程(守护进程一般以d结尾);
init提供property service(属性服务)来管理Android系统的属性。
init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

Linux Kernel完成系统设置后,会首先在系统中寻找init.rc文件,并启动init进程。

由于init中都是C语言代码,看不懂,不深入看源码了。简单了解下启动zygote的部分。在init.zygote.rc文件中,zygote服务定义如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd

通过init_parser.cpp完成整个service解析工作,此处就不详细展开讲解析过程,该过程主要工作是:

创建一个名叫”zygote”的service结构体;
创建一个用于socket通信的socketinfo结构体;
创建一个包含4个onrestart的action结构体。

Zygote服务会随着main class的启动而启动,退出后会由init重启zygote,即使多次重启也不会进入recovery模式。zygote所对应的可执行文件是/system/bin/app_process,通过调用pid =fork()创建子进程,通过execve(svc->args[0], (char**)svc->args, (char**) ENV),进入App_main.cpp的main()函数。故zygote是通过fork和execv共同创建的

2.2.Zygote进程

在Zygote进程创建完成之后,会进入java世界,即ZygoteInit.java。

问:我们知道Java调用C++可以通过JNI。那么C++是如何转到Java的,也就是说ZygoteInit.java这个类是如何被调用的?
答:在java中,class文件是由ClassLoader来加载的,但实际上,ClassLoader在加载java文件的过程中,也是通过C++来完成的(Bootstrp loader就是用C++写的,具体可以去看java类加载过程及机制,Java类加载器ClassLoader总结),所以C++如果想要访问java文件的话,是非常轻松的。如下:

接下里看ZygoteInit.java都做了些什么

这里第一步预加载的有系统的class文件,系统的资源文件,系统的动态库,因为我们所开发的应用在运行时会使用到大量的系统资源,如果这些资源在app启动的时候才加载,势必会造成app启动缓慢,而如果在Android系统启动的时候就将这些资源提前预加载,就可以达到提高启动app速度。

第三步这里的Socket服务是用来接受来自ActivityManagerService申请进程创建的请求的。然后就会进入到阻塞状态,等待连接。

SystemServer进程创建后会做什么,看一下SystemServer.java这个类:

先看main方法:

/*** The main entry point from zygote.*/public static void main(String[] args) {new SystemServer().run();}

接着看run()方法,主要是创建了系统服务的管理者,并启动了一些服务

 private void run() {...// Create the system service manager. //创建系统服务的管理者mSystemServiceManager = new SystemServiceManager(mSystemContext);...// Start services.  try {t.traceBegin("StartServices");//启动引导服务startBootstrapServices(t);       //启动核心服务startCoreServices(t);//启动其它一些服务         startOtherServices(t);          } catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {t.traceEnd(); // StartServices}}

在SystemServer中,启动了非常多的服务,这些服务都交给SystemServiceManager来管理。

其中其它服务一共有90+。这些服务都是通过startService方式启动,并注册到SystemServiceManager当中的。如:

 //启动包管理服务mSystemServiceManager.startService(new OverlayManagerService(mSystemContext));//启动传感器服务mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));

这些系统服务就构成了Android的FramWork层。为上层的app开发和运行提供了保障。所以SystemServer这个进程是在系统的启动流程中,我们需要重点了解的。

当这些服务启动完成之后;其中的ActivityManagerService最终会调用systemReady()方法。

     // We now tell the activity manager it is okay to run third party// code.  It will call back into us once it has gotten to the state// where third party code can really run (but before it has actually// started launching the initial applications), for us to complete our// initialization.mActivityManagerService.systemReady(() -> {Slog.i(TAG, "Making services ready");t.traceBegin("StartActivityManagerReadyPhase");mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);t.traceEnd();t.traceBegin("StartObservingNativeCrashes");try {mActivityManagerService.startObservingNativeCrashes();} catch (Throwable e) {reportWtf("observing native crashes", e);}t.traceEnd();

注意systemReady这个方法,注释的意思大概是:我们是时候去通知ActivityManager去启动第三方应用了。当三方应用真的可以运行的时候会通知我们,以便我们完成初始化。括号里面的内容大概是:在它(三方应用)启动之前会先启动launcher应用。

Android 系统启动流程总结:

第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,BootLoader检查RAM,初始化硬件参数等功能;

第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;

第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动init进程 ,这些在Native层中;

第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;

第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);SystemServer负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;

第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都有zygote fork生成。

到这里,系统开机到桌面应用准备就完成了,接下来就是launcher应用启动流程分析。

三、Launcher启动流程

3.1.Launcher启动流程关键类介绍:

ActivityManagerService
负责管理四大组件和进程,包括生命周期和状态切换。它的systemReady()方法,正是launcher应用启动的入口。

ActivityTaskManagerService
把原先在ActivityManagerService中负责Activity管理和调度等工作转移到了这里。ActivityTaskManagerService是Android10中新增的。

RootActivityContainer:
调用packageManagerService中去查询手机系统中已安装的所有的应用,哪一个符合launcher标准,且得到一个Intent对象,并交给ActivityStarter。

ActivityStarter
做启动之前的各项检查,比如Activity是否有在清单文件注册,Class文件是否存在等等。

ActivityRecord:
在Server端对activity的一种映射,记录和存储activity的信息。

TaskRecord
记录一个或多个ActivityRecord的实例

ActivityStack:
应用的任务栈的管理者

ActivityStackSupervisor
负责所有Activity栈的管理,包括launcher和非launcher应用。

ProcessList:
把原先在AMS中启动进程的工作转移到这里,是Android10中新增的。

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

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

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

TransactionExecutor:
主要作用是执行ClientTransaction

ClientLifecycleManager:
生命周期的管理调用

3.2.launcher启动流程分析:

Launcher的启动由三部分启动:

1.SystemServer完成启动Launcher Activity(符合launcher应用的最佳Activity)的调用2.Zygote fork出launcher进程。3.ActivityThread的main()方法,完成最终Launcher的onCreate操作

3.2.1.第一阶段:SystemServer启动Launcher应用调用阶段

调用栈如下:

前面我们知道了ActivityManagerService的systemReady()正是Launcher启动的入口。在其中会去调用startHomeOnAllDisplays()来启动Launcher.

[ActivityManagerService.java]中代码:这个方法大概有200多行,只展示关键点:


public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {...//启动HomeActivity(即Launcher应用的入口Activity):本意是在所有的屏幕上启动桌面应用,因为Android10.0开始是支持多屏幕的,比如手机屏幕,虚拟投屏,外接屏幕mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");...
}

这里的mAtmInternal是ActivityTaskManagerInternal,是一个抽象类。

/*** Activity Task manager local system service interface.* @hide Only for use within system server*/
public abstract class ActivityTaskManagerInternal {...
}

真正的实现是在ActivityTaskManagerService的内部类LocalService中。

这里有个阅读源码的技巧,一般以Internal结尾的抽象类,其实现类如下图所示,都在其对应的Service结尾的内部类LocalService中。

所以我们可以找到ActivityTaskManagerService的内部类LocalService,它继承自ActivityManagerInternal,确实有startHomeOnAllDisplays()方法。这里最终调用到RootActivityContainerstartHomeOnDisplay()方法

   final class LocalService extends ActivityTaskManagerInternal {...@Overridepublic boolean startHomeOnAllDisplays(int userId, String reason) {synchronized (mGlobalLock) {return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);}}...}

前面提到RootActivityContainer的作用是:调用packageManagerService中去查询手机系统中已安装的所有的应用,哪一个符合launcher标准,且得到一个Intent对象,并交给ActivityStarter

这里会一直调用到RootActivityContainer.startHomeOnDisplay()方法:


boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,boolean fromHomeKey) {...if (displayId == DEFAULT_DISPLAY) {//关键点1:构建一个category为CATEGORY_HOME的Intent,表明是HomeActivity(我觉得这个说法太含混,应该表明是构建一个符合launcher应用的Intent)homeIntent = mService.getHomeIntent();//关键点2:通过PMS从系统所用已安装的引用中,找到一个符合homeIntent的ActivityaInfo = resolveHomeActivity(userId, homeIntent); } ...//关键点3:启动launchermService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,displayId);return true;
}

获取的displayId为DEFAULT_DISPLAY, 通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是一个符合launcher应用的Intent;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合该Intent的Activity,最终调用startHomeActivity()来启动Activity

然后看下ActivityTaskManagerService.getHomeIntent()方法:主要就是构建一个
符合launcher应用的Intent。

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);//表明是符合launcher的Intent}return intent;

RootActivityContainer.resolveHomeActivity()方法:


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;
}

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

然后是ActivityStartController.startHomeActivity()方法:
这个类唯一的作用就是配置activity启动前的一些信息,并把这些信息传递给ActivityStart去做启动。


void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {....//关键点:obtainStarter方法返回一个 ActivityStarter对象,它负责 Activity 的启动mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason).setOutActivity(tmpOutRecord).setCallingUid(0).setActivityInfo(aInfo).setActivityOptions(options.toBundle()).execute(); // 关键点:execute()会触发 ActivityStarter的execute方法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();}
}

ActivityStarter.execute()方法:

int execute() {...if (mRequest.mayWait) {return startActivityMayWait(...)} else {return startActivity(...) }...
}

由于obtainStarter方法没有调用setMayWait的方法做任何配置,因此mRequest.mayWait为false,会走startActivity流程

ActivityStarter. startActivity()方法:

这个方法主要用来做activity启动之前的安全校验

关键点:int err = ActivityManager.START_SUCCESS

这里的caller,只有当应用进程创建完成之后,Server端才能拿到这个对象不为空的值,由于此时launcher应用的进程还未创建,所以此时caller对象一定为空。

还会做一些其它的校验,包括后台启动activity,activity启动权限等,其它如:

接着会调用到ActivityStarter.startActivityUnchecked方法

其中computeLaunchingTaskFlags(),是根据activity的launcher mode和intent.flag计算出activity的入栈方式。computeSourceStack()计算从哪个任务栈启动该activity。

这个方法一路会调用到

RootActivityContainer.resumeFocusedStacksTopActivities()方法:


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()focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}
}

中间还会走到ActivityStack中调用方法,如:

由于此时launcher进程没有创建完成,所以走到else中,然后调用到

接着看ActivityStackSupervisor.startSpecificActivityLocked()


void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {...//最终调用到AMS的startProcess()final Message msg = PooledLambda.obtainMessage(//这里的::是java8中的一个关键字,主要解决java8之前方法不能作为其它方法参数的问题ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());mService.mH.sendMessage(msg);...
}

ActivityManagerService.startProcess()方法:开始创建进程

然后调用startProcessLocked方法,

在startProcessLocked中,又进一步把进程创建工作委派给了ProcessList,这是Android10中对FrameWork进行改造而引入的,在老的版本中对进程的创建是在AMS中去发起请求的,谷歌团队认为AMS已经非常臃肿了(改造前2.8W行,改造后1.9W行),所以引入ProcessList专门进行进程的创建。

接着看ProcessList.startProcessLocked方法:

主要作用是,在进程创建之前,会配置一些必要的参数,比如版本号之类的。
接着,这个方法中有一个非常重要的参数:

entryPoint就是新进程的入口。

在创建进程的时候,在这里强制指定为android.app.ActivityThread.

所以,所有Android应用的进程入口是ActivityThread。并不是我们通常理解的application。

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

此时还是处于SystemServer进程。这个类的目的是创建本地socket连接对象,并且连接远在Zygote进程的socket服务,然后通过字符输入流,把创建进程所需要的参数发送过去,进程创建完成后,会根据传递的新进程的入口类,由zygotInit反射执行。

创建进程的调用栈如下:

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

Zygote的启动过程我们前面有简单了解。SystemServer的AMS服务向启动launcher发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。

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

Zygote的调用栈如下:

ZygoteInit.main():

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()来进行进程的处理caller = zygoteServer.runSelectLoop(abiList);...if (caller != null) {caller.run(); //执行返回的Runnable对象,进入子进程}
}

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

ZygoteConnection.processOneCommand()


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...return handleChildProc(parsedArgs, descriptors, childPipeFd,parsedArgs.mStartChildZygote);} else {//in parent...childPipeFd = null;handleParentProc(pid, descriptors, serverPipeFd);return null;}
}

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

ZygoteConnection.handleChildProc():

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 */);}}
}

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

然后把之前传来的"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);}}
}

到这里,就执行到了ActivityThread的main()方法。

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

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

ActivityThread.main():Java程序的入口,直接找到main方法。


public static void main(String[] args) {...//初始化looperLooper.prepareMainLooper();...ActivityThread thread = new ActivityThread();//建立Binder通道 (创建新线程)thread.attach(false, startSeq);...//主线程开始轮训,如果退出,说明程序关闭Looper.loop();
}

正式因为在进程的入口方法里面开始了消息队列的轮训,所以主线程才有了消息分发的机制。

ActivityThread的attach会一直调用到AMS的attachApplication方法。

ActivityManagerService.attachApplication()


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);......}
}

在这个方法中,又调用一系列方法,这里省略大量代码。最终主要做了两件事:
1.调度ActivityThread创建Application,并调用了application的onCreate()方法。如图:

2.继续启动进程创建之前已经加入任务栈的那个Activity,也就是Launcher应用的第一个Activity。
mAtmIntetnal.attachApplication(…),这里的mAtmIntetnal是ActivityTaskManagerInternal。这个方法的作用就是启动launcher应用的第一个Activity。根据前面讲的阅读源码技巧,这里可以找到该方法的实现在ActivityTaskManagerService中:

这里进一步交给了RootActivityContainer,接着看,这里很关键:

终于层层调用到ActivityStackSupervisor.java的 **realStartActivityLocked()**进行Activity的启动了。

ActivityStackSupervisor.realStartActivityLocked():


boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {try {//创建一个启动Activity的事务对象final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);//往事务里面添加一个任务,叫LaunchActivityItemclientTransaction.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;//这里就是上面提到的andResume参数,只有当该Activity在栈顶才为True.if (andResume) {//执行Activity的resume生命周期方法lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());} else {//执行Activity的pause生命周期方法lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);//开始事务的执行mService.getLifecycleManager().scheduleTransaction(clientTransaction);...}

这里的LaunchActivityItem,ResumeActivityItem等也是在Android10.0的改动,把Activity的生命周期拆分成ActivityLifecycleItem,根据不同的状态让不同的ActivityLifecycleItem去执行不同的activity的生命周期,这种设计模式叫做状态机

在状态机模式中,将每一个条件的分支,放入一个独立的类中,去除过多的 if else 分支语句。

接着看上面,一旦执行了scheduleTransaction开启事务,就会调用到LaunchActivityItem的excute方法。然后会调用到ClientTranscationHandler的handlerLaunchActivity方法。

我们知道ClientTranscationHandler是ActivityThread的父类,是一个抽象类,所以直接找到ActivityThread中去查看,在ActivityThread的handlerLaunchActivity中又会调用到performLaunchActivity方法:


这个方法就会去真正的启动Activity,并且返回一个Activity对象。当得到这个Activity的实例对象之后,接着看该方法下面的代码:


跟进这个方法:


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);}...
}
同理:如果还往事务中添加了ResumeActivityItem,相应的也会执行到Activity的onResume生命周期。

好了,到这里终于看到我们熟悉的Activity的onCreate(),到这里Launcher应用才启动完成,Launcher被真正创建起来。

Android系统开机到Launcher启动流程分析相关推荐

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

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

  2. Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】

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

  3. openharmony标准系统移植之init启动流程分析

    接上篇移植openharmony标准系统后,系统进入终端后,发现执行指令特别卡顿,太影响调试了.目前还不知道是什么问题导致的,不知道是不是cpu性能不够,但是感觉不太像是这个问题,卡顿如下图.基本一个 ...

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

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

  5. android 开机向导加载过程,开机向导启动流程分析

    开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygote进程是整个 ...

  6. Android开机向导启动流程分析

    Android开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygo ...

  7. Android Activity的启动流程分析:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互

    文章目录 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity: Step 1. Laun ...

  8. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  9. PackageManagerService启动详解(七)之扫描系统应用安装目录阶段流程分析

    PKMS启动详解(七)之BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段流程分析 Android PackageManagerService系列博客目录: PKMS启动详解系 ...

最新文章

  1. 模拟spring - 简单实现spring IOC
  2. Oracle-Listener log解读
  3. mysql中的order by
  4. PHP验证码常用的函数记录
  5. java for update 无效_java.sql.BatchUpdateException:调用中的无效参数
  6. 用yeoman搭建react画廊项目笔记
  7. 完成这些事情后再做决定 、
  8. 军哥 LNMP 常见问题
  9. Centos 7 telnet 详解
  10. 学会写出"图形界面+数据库"的程序要多长时间?
  11. 45、我的C#学习笔记11
  12. mysql oldaltertable_MySQL5.6 ALTER TABLE 分析和测试
  13. [游戏开发]iOS 游戏开发教程资源
  14. 基于服务的多源异构数据整合平台解决方案
  15. 哈佛幸福课-完美主义
  16. java中PO、BO、VO、DTO、POJO、DAO是什么?
  17. windows 下用开源流媒体压力测试工具 rtmpstress 测试RTMP媒体服务器负载性能
  18. 阿里内部隐藏「P」序列职级,「高P」光环或成过去式
  19. c++刷题_今日刷题(5)
  20. Google Code Jam 2014 -- C

热门文章

  1. 目标检测模型常用评价指标-(AP、mAP)
  2. 电商秒杀系统设计分析
  3. STM32基于HAL工程读取DHT11数据
  4. 活动目录是做什么用的
  5. Windows10设置自动重启或定时重启的方法
  6. 天天生鲜项目——注册页面
  7. JavaWeb学习第二十七天——项目实例
  8. 2007-05-12
  9. vue项目部署服务器两个域名,Vue项目服务器部署之子目录部署方法_飛雲_前端开发者...
  10. 好客php在线客服源码搭建教程可对接网页/小程序/微信公众号等