Android 系统服务启动 SystemServer

目录

技术答疑,成长进阶,可以加入我的知识星球:音视频领域专业问答的小圈子

在之前 Android 系统服务管理 ServiceManager 中学习了各种系统服务 Service 都是通过 ServiceManager 来管理的,从 ServiceManager 中来获得系统服务的 Binder 对象引用。这内容涉及到了 ContextImpl 类、SystemServiceRegistry 类、ServiceManager 类、ServiceManagerNative 类等等。

那么问题就来了,ServiceManager 所管理的那些 Service 的 Binder 对象引用又是何时注册添加的呢?

事实上这些服务 Service 是 SystemServer 进程中启动的。

SystemServer 系统服务

SystemServer 是由 Zygote 孵化的第一个进程,它和系统服务有着重要关系,通过 ps 命令,可知其进程名为 system_server 。Zygote 的进程名称为app_process

Android 系统中几乎所有的核心服务都在这个进程中,如 ActivityManagerService,PowerManagerService 和 WindowManagerService 等。

Zygote 为启动 SystemService 提供了专门的函数 forkSystemServer,而不是标准的forkAndSpecialize函数。

而 SystemServer 的执行主要在其 main 方法中,Android 6.0 的源码中不再是以前 Android 4.x 的 init1,init2 方法了。

1 /**
2     * The main entry point from zygote.
3     */
4    public static void main(String[] args) {
5        new SystemServer().run();
6    }
JAVA

继续跟进 run 方法查看:

 1 private void run() {
 2        try {
 3           
 4	        // 如果当前系统时间比 1970 年更早,就设置当前系统时间为 1970 年
 5            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
 6                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
 7                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
 8            }
 9
10        
11            // Here we go!
12            Slog.i(TAG, "Entered the Android system server!");
13            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
14
15            // Ensure binder calls into the system always run at foreground priority.
16            // 确保当前系统进程的 binder 调用,总是运行在前台优先级
17            BinderInternal.disableBackgroundScheduling(true);
18
19            // Prepare the main looper thread (this thread).
20            android.os.Process.setThreadPriority(
21                android.os.Process.THREAD_PRIORITY_FOREGROUND);
22            android.os.Process.setCanSelfBackground(false);
23            
24            Looper.prepareMainLooper();
25
26            // Initialize native services.加载本地服务
27            System.loadLibrary("android_servers");
28
29            // Check whether we failed to shut down last time we tried.
30            // This call may not return.
31            performPendingShutdown();
32
33            // Initialize the system context.初始化系统上下文
34            createSystemContext();
35
36            // Create the system service manager.创建系统服务管理
37            mSystemServiceManager = new SystemServiceManager(mSystemContext);
38            // 将 mSystemServiceManager 添加到本地服务 LocalServices 的成员 sLocalServiceObjects
39            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
40        } finally {
41            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
42        }
43
44        // Start services.
45        try {
46            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
47            // 启动服务代码
48            startBootstrapServices();
49            startCoreServices();
50            startOtherServices();
51        } catch (Throwable ex) {
52            Slog.e("System", "******************************************");
53            Slog.e("System", "************ Failure starting system services", ex);
54            throw ex;
55        } finally {
56            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
57        }
58
59        // Loop forever.
60        Looper.loop();
61        throw new RuntimeException("Main thread loop unexpectedly exited");
62    }
JAVA

在 main 方法中删除了一些与虚拟机有关的代码,只关心系统服务的启动就好。

在启动系统服务之前还初始化了系统环境上下文 createSystemContext(),执行了此方法之后mSystemContext变量才不会为 null ,关于如何初始化系统环境的上下文 Context ,必须得在写一篇博客单独学习了。

初始化 mSystemContext 之后,就是启动服务了:

  • startBootstrapServices(); // 启动引导服务
  • startCoreServices(); // 启动核心服务
  • startOtherServices(); // 启动其他服务

SystemServer 进程启动系统服务方式

SystemServer 进程启动系统服务有两种方式,分别是 SystemServiceManager 的startService 方式和 ServiceManager 的 addService 方式。

1       ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
2       Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
3       mSystemServiceManager.startService(TelecomLoaderService.class);
JAVA

startService 方式

通过 SystemServiceManager 的startService(Class<T> serviceClass)用于启动继承于SystemService抽象类的服务。

主要功能如下:

  • 通过反射创建对应的 SystemService ,并调用其 onStart 方法。
  • 同时将创建是 SystemService 添加到 SystemServiceManager 的 mService 集合变量中。

addService 方式

通过 ServiceManager 的addService(String name, IBinder service)用于初始化继承于 IBinder 的服务。

主要功能如下:

  • 将对应服务的 Binder 对象添加到 SystemManager 中去。

之前有学习到 ServiceManager 是系统服务的管家,通过它来获得其他服务。然而,在启动系统服务时,有些服务竟然没有 addService 注册到 ServiceManager 中去。

事实上,有些服务即使在启动时没有注册进去,在启动之后也会注册到 ServiceManager 中去。

通过查看 SystemService这个抽象类的源码可知,有如下方法:

 1 /**
 2     * Publish the service so it is accessible to other services and apps.
 3     */
 4    protected final void publishBinderService(String name, IBinder service) {
 5        publishBinderService(name, service, false);
 6    }
 7
 8    /**
 9     * Publish the service so it is accessible to other services and apps.
10     */
11    protected final void publishBinderService(String name, IBinder service,
12            boolean allowIsolated) {
13        ServiceManager.addService(name, service, allowIsolated);
14    }
JAVA

而 ServiceManager 的对应方法为,最后一个变量设置 true 的话,则表示允许隔离的沙盒进程访问该服务。

 1/**
 2     * Place a new @a service called @a name into the service
 3     * manager.
 4     * 
 5     * @param name the name of the new service
 6     * @param service the service object
 7     * @param allowIsolated set to true to allow isolated sandboxed processes
 8     * to access this service
 9     */
10    public static void addService(String name, IBinder service, boolean allowIsolated) {
11        try {
12            getIServiceManager().addService(name, service, allowIsolated);
13        } catch (RemoteException e) {
14            Log.e(TAG, "error in addService", e);
15        }
16    }
JAVA

ServiceManager 启动时机

SystemServer 是一个进程,由 Zygote 孵化的第一个进程,而 ServiceManager 也是一个进程,并且 SystemService 启动系统服务时,可以向 ServiceManager 中注册服务,那么可想而知,ServiceManager 是比 SystemService 先启动的。

ServiceManager 是由 init.rc 进程启动的。

init.rc中有如下代码启动 ServiceManager 。

 1service servicemanager /system/bin/servicemanager
 2    class core
 3    user system
 4    group system
 5    critical
 6    onrestart restart healthd
 7    onrestart restart zygote
 8    onrestart restart media
 9    onrestart restart surfaceflinger
10    onrestart restart drm
JAVA

由于我编的 Android 源码里面竟然死活没找到上面的代码,附上源码链接地址为: https://android.googlesource.com/platform/system/core/+/android-6.0.0_r1/rootdir/init.rc

就这样,虽然跳过了很多细节的部分,但还是大概的明白了 Android 系统服务管理(ServiceManager)和启动(SystemServer)的流程。

其他的细节部分,每个部分都可在再继续深入学习了。

最后还是附图一张: android-SystemServer-function

参考

  1. 《Android内核剖析》
  2. 《深入理解Android》
  3. http://blog.csdn.net/nightduke1/article/details/44201317
  4. http://ticktick.blog.51cto.com/823160/1659473
  5. http://gityuan.com/2016/02/20/android-system-server-2/

欢迎关注微信公众号:音视频开发进阶

Licensed under CC BY-NC-SA 4.0
粤ICP备20067247号
使用 Hugo 构建    主题 StackedJimmy 设计,Jacob 修改