美文网首页Andriod
启动流程 | SystemService

启动流程 | SystemService

作者: 力卉编程 | 来源:发表于2019-12-29 11:03 被阅读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的表象处理,并没有涉及对应的实际实现,是一个接口类的实现。

    完~~~

    文 | 力卉编程

    相关文章

      网友评论

        本文标题:启动流程 | SystemService

        本文链接:https://www.haomeiwen.com/subject/xukyoctx.html