Andriod

启动流程 | SystemService

2019-12-29  本文已影响0人  力卉编程

什么是Manager

我们在Android开发过程中经常会用到各种各样的系统管理服务,如进行窗口相关的操作会用到窗口管理服务WindowManager,进行电源相关的操作会用到电源管理服务PowerManager,还有很多其他的系统管理服务,如通知管理服务NotifacationManager、振动管理服务Vibrator、电池管理服务BatteryManager…… 这些Manager提供了很多对系统层的控制接口。对于App开发者,只需要了解这些接口的使用方式就可以方便的进行系统控制,获得系统各个服务的信息,而不需要了解这些接口的具体实现方式。而对于Framework开发者,则需要了解这些Manager服务的常用实现模式,维护这些Manager的接口,扩展这些接口,或者实现新的Manager。

这些Manager接口的实现就是Service

调用流程

一个简单的SystemService

我们从一个简单的系统服务Vibrator服务来看一下一个系统服务是怎样建立的。
Vibrator服务提供的控制手机振动的接口,应用可以调用Vibrator的接口来让手机产生振动,达到提醒用户的目的。
从Android的官方文档中可以看到Vibrator只是一个抽象类,只有4个抽象接口:

abstract void cancel() 取消振动
abstract boolean hasVibrator() 是否有振动功能
abstract void vibrate(long[] pattern, int repeat) 按节奏重复振动
abstract void vibrate(long milliseconds) 持续振动

应用中使用振动服务的方法也很简单,如让手机持续振动500毫秒:

Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);

Vibrator使用起来很简单,我们再来看一下实现起来是不是也简单。
从文档中可以看到Vibrator只是定义在android.os 包里的一个抽象类,在源码里的位置即frameworks/base/core/java/android/os/Vibrator.java,那么应用中实际使用的是哪个实例呢?应用中使用的Vibrator实例是通过Context的一个方法getSystemService(Context.VIBRATOR_SERVICE)获得的,而Context的实现一般都在ContextImpl中,那我们就看一下ContextImpl是怎么实现getSystemService的:

//frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}

frameworks/base/core/java/android/app/SystemServiceRegistry.java
(SystemServiceRegistry是 Android 6.0之后才有的,Android 6.0 之前的代码没有该类,下面的代码是直接写在ContextImpl里的)

 public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

SYSTEM_SERVICE_MAP是一个HashMap,通过我们服务的名字name字符串,从这个HashMap里取出一个ServiceFetcher,再return这个ServiceFetcher的getService()。ServiceFetcher是什么?它的getService()又是什么?既然他是从SYSTEM_SERVICE_MAP这个HashMap里get出来的,那就找一找这个HashMap都put了什么。
通过搜索SystemServiceRegistry可以找到如下代码:

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

这里往SYSTEM_SERVICE_MAP里put了一对String与ServiceFetcher组成的key/value对,registerService()又是从哪里调用的?继续搜索可以发现很多类似下面的代码:

static {
    registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
            new CachedServiceFetcher<AccessibilityManager>() {
        @Override
        public AccessibilityManager createService(ContextImpl ctx) {
            return AccessibilityManager.getInstance(ctx);
        }});

    ...
    registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
            new CachedServiceFetcher<Vibrator>() {
        @Override
        public Vibrator createService(ContextImpl ctx) {
            return new SystemVibrator(ctx);
        }});
    ...
}

SystemServiceRegistry的static代码块里通过registerService注册了很多的系统服务,其中就包括我们正在调查的VIBRATOR_SERVICE,通过结合上面的分析代码可以可以知道getSystemService(Context.VIBRATOR_SERVICE)得到的是一个SystemVibrator的实例,通过查看SystemVibrator的代码也可以发现SystemVibrator确实是继承自Vibrator:

public class SystemVibrator extends Vibrator {
    ...
}

我们再从SystemVibrator看一下系统的振动控制是怎么实现的。以hasVibrator()为例,这个是查询当前系统是否能够振动,在SystemVibrator中它的实现如下:

public boolean hasVibrator() {
    ...
    try {
        return mService.hasVibrator();
    } catch (RemoteException e) {
    }
    ...
}

这里直接调用了一个mService.hasVibrator()。mService是什么?哪来的?搜索一下可以发现:

private final IVibratorService mService;
public SystemVibrator() {
    ...
    mService = IVibratorService.Stub.asInterface(
            ServiceManager.getService("vibrator"));
}

AIDL (Android Interface Definition Language) 是Android中的接口定义文件,为系统提供了一种简单跨进程通信方法。
IVibratorService 中定义了几个接口,SystemVibrator中使用的也是这几个接口,包括我们刚才使用的hasVibrator()

//frameworks/base/core/java/android/os/IVibratorService.aidl
interface IVibratorService
{
    boolean hasVibrator();
    void vibrate(...);
    void vibratePattern(...);
    void cancelVibrate(IBinder token);
}

这里又只是接口定义,接口实现在哪呢?通过在frameworks/base目录下进行grep搜索,或者在AndroidXRef搜索,可以发现IVibratorService接口的实现在

//frameworks/base/services/java/com/android/server/VibratorService.java
public class VibratorService extends IVibratorService.Stub

可以看到 VibratorService实现了IVibratorService定义的所有接口,并通过JNI调用到native层,进行更底层的实现。

VibratorService是怎么注册为系统服务的呢?在SystemServer里面:
VibratorService vibrator = null;
...
//实例化VibratorService并添加到ServiceManager
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...
//通知服务系统启动完成
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady");
try {
    vibrator.systemReady();
} catch (Throwable e) {
    reportWtf("making Vibrator Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

这样在SystemVibrator里就可以通过下面的代码连接到VibratorService,与底层的系统服务进行通信了:

IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));

此文仅是告诉一下Service的表象处理,并没有涉及对应的实际实现,是一个接口类的实现。

完~~~

文 | 力卉编程

上一篇 下一篇

猜你喜欢

热点阅读