简介
SystemServer进程是Java层的第二个进程。其中运行着所有Java层的系统服务,并管理着这些服务的“服务端”。
启动后的准备工作
对比应用进程,可以看出是很相似的。
在ZygoteInit.handleSystemServerProcess()中。
- 关闭从Zygote那里继承下来的Socket;
- 设置一些进程参数;
- 做些常规初始化;
- 在Native层启动一个线程池,用于Binder通信;
- 设置进程名为“system_server”;
- 调用com.android.server.SystemServer类的main函数。
启动系统服务
在SystemServer.main() -> SystemServer.run()中:
- 在Java层加载libandroid_servers.so;
- 在Native层启动SurfaceFlinger进程;
- 在Java层创建SystemContext;
- 创建LocalServices;
- 创建SystemServiceManager,并注册到LocalServices;
- 启动各个系统级服务;
- 主线程进入Loop循环,用于接收系统级服务的工作线程发送来的信息;
- 系统级服务启动后都运行于SystemServer进程,其中AMS有两个线程“主线程”和“工作线程”,其它服务都只有“工作线程”。
Android运行环境
Android希望淡化进程的概念,转而使用组件的概念。Android中的组件有:“应用”、“窗口”、“系统服务”、“应用服务”、“内容提供者”、“广播接收者”。
怎么在“进程”和“组件”之间转换呢?每个进程对应一个ActivityThread。ActivityThread的功能主要有两个:控制运行在该进程的组件的生命周期;为“应用”、“窗口”、“服务”组件创建Context。
Context封装了“组件运行的环境信息”,并提供了“与环境交互的接口”和“与其他组件交互的接口”。针对不同的组件,Android提供了不同的Context子类。
系统服务:ContextImpl
- 获取AssetManager;
- 获取Resource;
- 获取向PMS发送信息的客户端PackageManager;
- 获取向ContentProvider发送信息的工具类ContentResolver;
- 获取主线程Loopper;
- 获取所属应用的ApplicationContext;
- 设置/获取所属应用的主题;
- 获取所属应用的类加载器;
- 获取所属应用的包名;
- 获取所属应用的应用信息ApplicationInfo;
- 获取所属应用的资源文件夹(/data/app/包名/res/)路径;
- 获取所属应用的代码文件夹(/data/app/包名/)路径;
- 获取所属应用的某个SP文件路径;
- 获取操作所属应用的某个SP文件的工具类SharedPreferences;
- 打开某个文件(必须在所属应用的文件集中)的输入流/输出流;
- 删除某个文件(必须在所属应用的文件集中);
- 获取所属应用的文件集的路径(/data/data/包名/files/);
- 获取SD卡上某类资源的文件夹路径;
- 获取所属应用在SD卡上的独占文件夹的路径;
- 获取所属应用的缓存文件夹的路径(/data/data/包名/cache/);
- 打开或创建所属应用的某个数据库;
- 删除所属应用的某个数据库;
- 获取所属应用的数据库文件夹(/data/data/包名/databases/);
- 列出所有数据库文件;
- 开启某个“窗口”组件(必须设置FLAG_NEW_TASK);
- 开启多个“窗口”组件(必须设置FLAG_NEW_TASK);
- 向其他应用发送一个Intent;
- 发送/删除一条广播;
- 注册/注销一个“广播接收者”组件;
- 启动/停止/绑定/解绑一个“应用服务”组件;
- 检查所属应用是否拥有某项权限;
应用:Application
- 作为ContextImpl的装饰类,有ContextImpl的所有接口;
- 注册/注销ComponentCallback;
- 注册/注销ActivityLifecycleCallback
窗口:Activity
- 作为ContextImpl的装饰类,有ContextImpl的所有接口;
- 获取/重置开启本组件的Intent;
- 获取所属应用的Application;
- 获取向WMS发送信息的客户端WindowManager;
- 获取操作窗口的工具类PhoneWindow;
- 获取当前焦点的控件;
- 获取FragmentManager;
- 获取/设置控件树;
- 获取/设置Transition动画;
- 为所属应用申请某些权限;
- 开启某个“窗口”组件(不必设置FLAG_NEW_TASK);
- 开启多个“窗口”组件(不必设置FLAG_NEW_TASK);
- 设置对之前窗口的返回结果;
- 获取之前窗口的类名/包名;
- 设置控件树的可见性;
- 获取本组件的关闭状态(是正在关闭还是已经关闭了);
- 销毁本组件;
- 销毁本组件及所属Task中的其他窗口组件;
- 销毁本组件及所属Task;
- 关闭但不销毁本组件;即关闭本窗口,但不删除AMS中记录,当用户返回本窗口时会重建本窗口;
- 获取/设置窗口方向;
- 获取所属Task的ID;
- 判断本组件是否是所属Task的root;
- 把所属Task移动到后台;
Application 和 Activity 的 区别
- 从组件生命周期的角度考虑,Application的生命周期和“应用”一样长,Activity的生命周期和“窗口”一样长。当引用对象的生命周期比窗口的生命周期长,就不能用Activity,否则会造成内存泄漏。
- 从WMS的角度考虑,Activity可以对应到WindowToken,而Application无法对应到。所以当要添加子窗口时,必须用Activity。
- 从AMS的角度考虑,Activity可以对应到TaskRecord,而Application无法对应到。所以当要启动“窗口”组件时,要么用Activity,要么用Application + FLAG_NEW_TASK。
getApplication() 和 getApplicationContext() 的区别
同一个Application对象在3个阶段被赋值到3个对象的引用。
- 当应用包信息被PMS管理后,被应用对应的LoadedApk对象引用。即LoadedApk.mApplication。
- 当应用启动后,被应用对应的ActivityThread对象引用。即ActivityThread.mApplication。
- 当某个“窗口”组件启动后,被该组件引用。即Activity.mApplication。
getApplication()返回的是Activity.mApplication;getApplicationContext()返回的是LoadedApk.mApplication或ActivityThread.mApplication。
LocalServices、SystemServiceManager
在Binder机制建立前,系统服务注册在LocalServices。LocalServices不要求注册的服务继承自Binder和SystemService类。
在Binder机制建立后,LocalServices就没有用了。注册在LocalServices的服务都会再注册到SystemServiceManager,之后注册的服务也都直接注册到SystemServiceManager。SystemServiceManager要求注册的服务必须继承自Binder和SystemService类。SystemServiceManager的作用是管理系统服务的生命周期,与Binder通信无关。
管理系统服务的“服务端”
应用进程要获取系统服务的客户端,可以通过ServiceManager/ServiceManagerNative向ServiceManager进程发送消息。ServiceManagerNative是Binder机制业务层的服务端;ServiceManager是装饰层,增加了缓存和单例功能。