Android的Java层系统服务(AndroidService)
Android系统服务上接Framework框架层,下接HAL硬件抽象层,作为APP和硬件通信的中间管道之一,起着承上启下的重要作用,研究系统服务对APP层开发,ROM开发以及底层开发都有着不可替代的作用。本片文章主要介绍的有以下几个方面:
- 系统服务简介
- 系统服务的启动流程
- ActivityManagerService启动APP
- Binder通信
- APP绑定系统服务
系统服务简介
作为Android中重要的一环,系统服务是最接近Linux内核,设备驱动程序(HAL)层的,在这里我们默认把HAL作为Linux的驱动部分解释为Linux的一部分,所以可以说系统服务上接APP,下接Linux内核。系统服务按照开发的语言和运行层次不同,可以分为Java层系统服务和Native系统服务两中:
- Java层系统服务,该层的系统服务主要由Java语言编写,在这里我们称为Android系统服务(AndroidService),在APP中一般可以通过Context句柄获得对应的系统服务对象,主要包括AudioService,LocationManagerService,WindowManagerService,ActivityManagerService等。
- Native系统服务,该层系统服务主要由C/C++语言编写,在这里我们称为Native系统服务(NativeService),用于启动上层服务或者向上层系统服务提供基础运行环境,例如ServiceManager。
系统服务的启动流程
系统服务在Android开机的时候跟随系统启动,这个时期同时启动的系统服务有几十个,按照“硬件->bootloader->Linux内核->驱动->init->zygote->DalvikVM->SystemService->Framework->APP”这样的开机流程,其中从硬件到驱动的流程属于核心态的初始化,从init到APP的部分属于用户态的初始化,其中在系统服务中,最先启动的系统服务为SeriviceManager,该服务属于最先启动的最重要的系统服务,其他的系统服务都需要由该系统服务的帮助来启动。我们直接把AudioService的代码拿出来看一下:
ServiceManager.addService(Context.AUDIO_SERVICE,new AudioService(context));
可以看到ServiceManager的静态方法把创建出来的对象添加到了系统服务的启动列表中。
ActivityManagerService启动APP
系统启动完成之后,zygote会调用select()函数开启多路复用的IO模式,启动socket通信,并进入到一个Loop循环之中,等待在zygote的子进程发送消息,当ActivityManagerService要启动一个APP的时候,会通过socket发送消息到zygote,那么zygote就会调用fork函数创建子进程,该子进程就是APP要运行的进程,该进程通过JNI调用ActivitThread的main函数来启动ActivityThread,该线程就是APP所运行的主线程,有时我们也称为UI线程。也就是说不论运行了多少个APP,ActivityManagerService系统服务都只有一个,而且每个APP的进程都使用Binder的方式和ActivityManagerService进行IPC通信。
Binder通信
系统服务和APP之间都是通过Binder的方式进行IPC通信的,Binder的驱动程序在内核态被加载,在注册系统服务的时候会把系统服务的指针存到Binder驱动中,每一个系统服务如果想要和APP进行IPC通信,都要实现一个IBinder接口,APP通过该接口调用系统服务的函数,然后由系统服务操作Linux内核或者硬件完成任务,IBinder是Binder的一个父类接口。系统服务只需要继承Binder,实现对应的属于自身服务的特殊方法,APP从而可以调用到系统服务的方法。
APP绑定系统服务
APP如果需要使用系统服务,先要对系统服务进行绑定,绑定的时候需要使用到ServiceManager,由ServiceManager来协助APP进行绑定,例如我们需要使用AudioService,则绑定的代码为:
IBinder binder = ServiceManager.getService(Context.AUDIO_SERVICE);
当然该代码不需要我们APP来写,Context中已经进行了实现。绑定之后,ServiceManager就会从Binder驱动中找到对应的系统服务的指针。