目录
Android有哪些主要的系统进程?这些进程各自有什么作用?
参考文章:
Android系统启动流程(二)解析Zygote进程启动过程
以上三篇文章涉及到C语言源码,比较难懂。
这道题想考察什么?
- Android有哪些主要的系统进程?这些进程各自有什么作用?
- 这些系统进程是怎么启动的?
- 进程启动之后主要做了什么事情?
Android有哪些主要的系统进程?这些进程各自有什么作用?
在Android源码的init.rc文件中:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
...
service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics
onrestart restart zygote
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
...
init进程创建的系统进程:zygote、servicemanager、surfaceflinger、mediaserver等
zygote进程创建的系统进程:SystemServer
系统进程有很多,我们只需要关注Zygote和SystemServer就可以了。
zygote是怎么启动的?
Android系统启动流程(二)解析Zygote进程启动过程
以上文章得出的结论:
1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.创建DVM并为DVM注册JNI.
3.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4.通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5.启动SystemServer进程。
视频得出的结论:
- init进程fork出Zygote进程
- 启动虚拟机,注册JNI函数
- 预加载系统资源
- 启动SystemServer
- 进入Socket Loop
接下来看Zygote的工作流程:
在启动流程的最后一步,Zygote进入了一个loop循环,在这个循环里面,它一方面看有没有发过来socket消息,有消息的话就会执行如下的runOnce函数:
boolean runOnce(){
//readArgumentList() 读取发过来的参数列表
String[] args = readArgumentList();
//创建子线程 该函数返回两次,一次从父进程返回,一次从子进程返回
int pid = Zygote.forkAndSpecialize(...);
if(pid == 0){
//从子进程返回 这里其实就是调用ActivityThread.Main方法
handleChildProc(parsedArge, ...);
//should never get here,the child is expected to either
//throw ZygoteInit.MethodAndArgsCaller or exec().
return true
}else{
//从父进程返回
return handleParentProc(pid, ...);
}
}
SystemServer是怎么启动的?
Android系统启动流程(三)解析SyetemServer进程启动过程
我们看这个函数:
private static boolean startSystemServer(...){
String args[] = {
...
"com.android.server.SystemServer",
}
//通过Zygote.forkSystemServer 创建一个系统进程
int pid = Zygote.forkSystemServer(...);
if(pid == 0){
//SystemServer启动的具体逻辑
handleSystemServerProcess(parseArgs);
}
return true;
}
void handleSystemServerProcess(Arguments parsedArgs){
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, ...);
}
void zygoteInit(String[] argv,...){
//常规的一些初始化
commonInit();
//见下面的onZygoteInit函数
nativeZygoteInit();
//见下面的applicationInit函数
applicationInit(argv, ...);
}
//启动binder机制,并且启动一个binder线程
virtual void onZygoteInit(){
sp<ProcessState> proc = ProcessState::self();
proc -> startThreadPool();
}
//调用Java类的入口函数,这个Java类其实就是SystemServer类
void applicationInit(...){
invokeStaticMain(args, ...);
}
//我们来看SystemServer类的入口函数
public static void main(String[] args){
//看下面的 run方法
new SystemServer().run();
}
private void run(){
Looper.prepareMainLooper();
System.loadLibrary("android_servers");
createSystemContext();
startBootstrapServices();
startCoreServices();
startOtherServices();
Looper.loop();
}
SyetemServer在启动时做了如下工作:
- 1.启动Binder线程池,这样就可以与其他进程进行通信。
- 2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。
- 3.启动各种系统服务。
看两个问题
系统服务是怎么启动的?
系统服务怎么发布,让应用程序可见?
void publishBinderService(String name, IBinder service){
publishBinderService(name, service, false);
}
void publishBinderService(String name, IBinder service, ...){
ServiceManager.addService(name, service, allowlsolated);
}
如上,可以看到,最终还是把系统服务 的binder注册到了ServiceManager中
系统服务跑在什么线程?
主线程? 没有看到有哪个系统服务用到了主线程
工作线程?
工作线程分两种情况:
有的服务有自己独有的工作线程:例如AMS、PMS、PackageManagerService,
还有一些是大家共用的一些线程,比如:DisplayThread(负责显示) FgThread(负责前台任务) IoThread(负责IO任务) UiThread(负责UI显示,这个需要格外关注,一般我们认为UiThread是主线程,可是从这里看出,它只是一个工作线程,因此充分说明UI的刷新不一定是要在主线程,在子线程也可以)
binder线程? 是在这个线程,因为应用跨进程调过来的时候,肯定首先就是binder线程里面
课堂作业:
- 为什么系统服务不都跑在binder线程里呢?
- 为什么系统服务不都跑在自己私有的工作线程里呢?
- 跑在binder线程和跑在自己私有的工作线程,怎么取舍?
怎么解决系统服务之间的互相依赖?
举例:服务A需要用到服务B的东西,而B有需要用到服务C的东西,这样就形成了一个依赖关系
在SystemServer中,系统服务大概有七八十个。要解决这些服务之间的互相依赖关系,不是一件简单的事情,
那么Android是怎么解决这个问题的呢?
- 1、分批启动:分为三批:比较基础的服务就先启动:例如AMS PMS PKMS,而一些上层的服务就晚些启动
- 2、分阶段启动:阶段1、阶段2、阶段3、...
系统服务启动完成以后,就到了桌面的启动了
桌面的启动:
在AMS服务就绪的时候会调用 systemReady函数:
public void systemReady(final Runnable goingCallback){
...
//可以把桌面看做一个单独的系统级应用
//该函数启动一个Activity,就是LauncherActivity
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
}
//LauncherActivity的onCreate方法中
mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags);
//这个mLoaderTask会向Package Manager Service查询所有当前已经安装的应用,
//然后把其以图标的形式显示在桌面上,当我们点击这个图标的时候,就会启用对应的LauncherActivity
mPm.queryIntentActivitiesAsUser
总结:
说说Android系统的启动流程?
这个问题该怎么回答?
对于该问题的回答,重点在于细节。如果只回答:先启动Zygote、在启动SystemServer、最后启动桌面。这样显然太简单,是不行的。主要围绕Zygote和SystemServer的启动流程来说就可以了。