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. }

继续跟进 run 方法查看:

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

在 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);

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. * Publish the service so it is accessible to other services and apps.
  9. */
  10. protected final void publishBinderService(String name, IBinder service,
  11. boolean allowIsolated) {
  12. ServiceManager.addService(name, service, allowIsolated);
  13. }

而 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. }

ServiceManager 启动时机

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

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

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

  1. service 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

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

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

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

最后还是附图一张:
《Android 系统服务启动 SystemServer》

参考

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/

原创文章,转载请注明: 转载自http://www.glumes.com/android-systemserver/

    原文作者:天涯海角路
    原文地址: https://www.cnblogs.com/aademeng/articles/7521853.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞