常见基础问题:
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会做各种启动前检查。
Google官方提供的经典分层架构图:
从下往上依次分为5层:
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生成的。
init进程, Zygote进程, SystemServer进程, ServiceManager进程。
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-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart 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共同创建的。
在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这个类(抽取最核心的代码):
在SystemServer的入口mian方法中,启动了非常多的服务,这些服务都交给SystemServerManager来管理。
其中其它服务一共有90+。这些服务都是通过startService方式启动,并注册到SystemServerManager当中的。如:
这些系统服务就构成了Android的FramWork层。为上层的app开发和运行提供了保障。所以SystemServer这个进程是在系统的启动流程中,我们需要重点了解的。
当这些服务启动完成之后;其中的ActivityManagerService最终会调用systemReady()方法。
注意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应用启动流程分析。
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:
生命周期的管理调用
Launcher的启动由三部分启动:
1.SystemServer完成启动Launcher Activity(符合launcher应用的最佳Activity)的调用
2.Zygote fork出launcher进程。
3.ActivityThread的main()方法,完成最终Launcher的onCreate操作
前面我们知道了ActivityManagerService的systemReady()正是Launcher启动的入口。在其中会去调用startHomeOnAllDisplays()来启动Launcher.
[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {
...
//启动HomeActivity:本意是在所有的屏幕上启动桌面应用,因为Android10.0开始是支持多屏幕的,比如手机屏幕,虚拟投屏,外界屏幕
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
}
这里的mAtmInternal.startHomeOnAllDisplays(),mAtmInternal是ActivityTaskManagerInternal,是一个抽象类
真正的实现是在ActivityTaskManagerService的内部类LocalService中。
这里有个阅读源码的技巧,一般以Internal结尾的抽象类,其实现类如下图所示,都在内部类LocalService中。
然后找到ActivityTaskManagerService的LocalService,它继承自ActivityManagerInternal,确实有startHomeOnAllDisplays()方法。这里最终调用到RootActivityContainer 的startHomeOnDisplay()方法
前面提到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的Activity
aInfo = resolveHomeActivity(userId, homeIntent);
}
...
//关键点3:启动launcher
mService.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_HOME
if (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为null
ActivityInfo 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) {
// 获取栈顶的ActivityRecord
final 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反射执行。
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出的第一个进程 SystmeServer
Runnable 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 表示子进程 的真正的PID
pid = 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传递过来的是 ActivityThread
return 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()方法。
Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来我们就从ActivityThread main()来分析Launcher的创建过程。
ActivityThread.main():Java程序的入口,直接找到main方法。
public static void main(String[] args) {
...
//初始化looper
Looper.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);
//往事务里面添加一个任务,叫LaunchActivityItem
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;
//这里就是上面提到的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被真正创建起来。