1. Android 启动过程是什么样?
Android 系统架构包括 Linux Kernel、HAL、Native C/C++ Library、Android Runtime、Java Api Framework、SystemApps 六块内容。
1.1. 开机过程:
-
启动电源以及系统启动
-
加载引导程序BootLoader到RAM中,拉起系统OS
-
内核启动后,查找init.rc文件,启动init进程
-
init进程主要用来初始化和启动属性服务,也用来启动Zygote进程
init进程的main方法中涉及几个重要函数:
- propery_init 对属性服务进行初始化
- singal_handler_init 设置子进程信号处理函数,防止子进程成为僵尸进程 (父进程fork出子进程后,子进程虽然已经退出,但在系统进程表中还保存一定的信息)
- parser.ParseConfig 解析init.rc文件
- restart_processes 重启死去的进程
init进程启动Zygote进程,zygote执行程序是app_main.cpp,通过以下代码启动
runtime.start("com.android.internal.os.ZygoteInit",args,zynote)
init进程初始化属性服务并启动属性服务,propery_init()、start_property_service() 在linux新内核中,epoll替换了select,epoll是linux内核为处理大批量文件描述符而做了改进的poll,是linux下多路复用I/O接口select/poll的增强版本。内部保存事件的数据是红黑树,select采用数组保存。
1.1.1. init进程启动总结:
- 创建和挂载启动所需的文件目录
- 初始化和启动属性服务
- 解析init.rc配置文件并启动zygote进程
1.1.2. Zygote进程
Zygote进程名为"app_process",zygote进程启动后会修改为"zygote",通过fork的形式来创建DVM/ART、应用程序进程、SystemServer进程
1.1.2.1. AndroidRunTime的start方法中做了什么事情呢?
- startVM : 启动Java虚拟机
- startReg : 为Java虚拟机注册JNI方法
- 获取Zygote的className ,com.android.internal.os.ZygoteInit
- 找到Java层的ZygoteInt类
- 通过JNI调用ZygoteInit的main方法,Zygote从Native层进入了Java框架层
1.1.2.2. ZygoteInit的main方法做了什么事情呢?
- zygoteServer.registerServerSocket : 创建一个Server端的Socket,socket名称为"zygote"
- preload : 预加载类和资源
- startSystemServer: 启动SystemServer进程
- zygoteServer.runSelectLoop : 等待AMS请求Zygote进程创建新的应用程序
1.1.2.3. SystemServer进程处理过程
SystemServer进程用于创建系统服务,如AMS、PMS、WMS等
Zygote进程启动了SystemServer进程,那么Zygote是如何处理SystemServer进程的呢?
startSystemServer中完成两件事:
* 关闭Zygote进程创建的Socket,这个Socket对于SystemServer没有用处
* 调用handleSystemServerProcess启动SystemServer进程
handleSystemServerProcess完成两件事:
* 调用 createPathClassLoader ,创建PathClassLoader
* 调用 ZygoteInit.zygoteInit ,在此方法中完成两件事情
* ZygoteInit.nativeZygoteInit: 启动Binder线程池
***调用Native层的AndroidRuntime的onZygoteInit创建Binder线程池,这样SystemServer就可以通过Binder和其他进程进行通信了。***
```C++
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
```
* RuntimeInit.applicationInit: 进入SystemServer的main方法中
* 在applicationInit方法的invokeStaticMain方法中通过反射得到SystemServer类
```Java
private static void invokeStaticMain(...){
// 通过反射找到SystemServer类
cl = Class.forName(className, true, classLoader);
...
// 找到SystemServer的main方法
m = cl.getMethod("main", new class[] {String[].class});
...
// 最后抛出一个异常,这个异常会在ZygoteInit的main方法被捕获
// 这个异常的处理会清除设置过程需要的堆栈帧,让SystemServer的main方法看起来像是SystemServer进程的入口方法
throw new Zygote.MethodAndArgsCaller(m,argv);
}
```
* 至此,System进程就进入到SystemServer的main方法中。
#### 1.1.2.4. SystemServer进程的解析
进入到SystemServer.main方法中
```Java
public sattic void main(String[] args){
new SystemServer.run();
}
private void run (){
try {
...
// 创建消息Looper
Looper.prepareMainLooper();
// 加载动态库libandroid_servers.so
System.loadLibrary("android_servers");
...
// 初始化系统上下文
createSystemContext();
// 创建系统服务管理,对系统服务进行创建、启动和生命周期管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
} finally {
...
}
try {
...
// 启动引导服务(如AMS、PMS、PowerManagerService、DisplayManagerService...)
startBootstrapServices();
// 启动核心服务(如日志、电池、WebView...)
startCoreServices();
// 启动其他服务(如WMS、IMS、相机、蓝牙、通知、定位)
startOtherServices();
}
}
在SystemServiceManager中有一个mServices的arrayList变量用来保存各种系统服务。 通过SystemServiceManager.startService(xxxx.class)可以完成把某个Service服务添加到mServices中,完成该服务的注册。还可以通过比如调用PackageManagerService.main()这种形式来完成启动系统服务。
public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore){
...
// 创建PackageManagerService
PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);
m.enableSystemUserPackages();
// 注册到ServiceManager中
ServiceManager.addService("package",m);
return m;
}
ServiceManager 用来管理系统中的各种Service ,用于系统C/S架构中的Binder通信机制。
1.1.2.5. SystemServer 进程总结
- 启动Binder线程池,这样就可以与其他进程进行通信
- 创建SystemServiceManager,完成对系统服务的创建、启动和生命周期管理
- 启动引导服务、核心服务、其他服务
1.2. Launcher的启动
Launcher在启动过程中会请求PMS获取系统已安装应用信息,然后将其封装成一个快捷图标列表显示在系统屏幕上。
SystemService进程在启动过程中会启动PMS,PMS启动后会把应用程序都安装成功,而Launcher是在AMS启动后被它启动起来的。
通过层层调用,最终调用到startActivityStarter方法中,剩下的就跟普通的Activity的调用类似了,最终会调用到Launcher的onCreate方法中。
Launcher是如何显示应用图标的?
protected void onCreate(...){
...
LauncherAppState app = LauncherAppState.getInstance();
...
mModel = app.setLauncher(this);
...
mModel.startLoader(...);
}
LauncherModel setLauncher(Launcher this){
getLocalProvider(mContext)。setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
return mModel;
}
public void initialize(Callbacks callbacks){
synchronized(mLock){
...
// 把传入的Launcher封装成弱引用对象
mCallbacks = new WeakReference<Callbacks>(callbacks);
}
}
在LauncherModel中,创建了sWorkerThread
HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
Handler sWorker = new Handler(sWorkerThread.getLooper());
public void startLoader(...){
...
mLoaderTask = new LoaderTask(mApp, isLaunching);
...
// 将LoaderTask作为消息传递给HandlerThread
sWorker.post(mLoaderTask);
}
private class LoaderTask implements Runnable {
...
// 加载工作区信息
loadWorkspace();
...
// 绑定工作区信息
bindWorkspace(mPageToBindFirst);
...
// 加载系统已经安装好的应用程序信息
loadAllApps();
}
private void loadAllApps(){
mHandler.post(new Runnable {
...
// 这个callbacks实际指向就是Launcher
callbacks.bindAllApplications(added);
})
}
public void bindAllApplications(final ArrayList<AppInfo> apps){
...
if(mAppViews != null){
// mAppViews类型为AllAppsContainerView
mAppViews.setApps(apps);
}
}
最终会调用到AllAppsContainerView的onFinishInflate方法中
protected void onFinishInflate() {
...
mAppsRecyclerView.setApps(mApps);
mAppsRecyclerView.setLayoutManager(...);
mAppsRecyclerView.setAdapter(...);
}
现在应用程序的快捷图标的列表就显示在屏幕上了。
1.2.1. 总结:Android的启动流程
- 启动电源以及系统启动
- 引导程序BootLoader
- Linux内核启动
- init进程启动
- Zygote进程启动
- SystemServer进程启动
- Launcher启动