Android系统服务管理者——ServiceManager

Android系统给我们提供了上百个服务,每一个服务都有一个服务中介类,例如WindowManager、ActivityManager等。 通常我们和系统服务进行交互都是通过服务中介来进行的。通过Context.getSystemService(String name)我们可以获取系统服务,并在客户端封装成中介类,然后通过该中介类去获取相关的系统服务。那么到底系统服务和中介类是怎么获取的呢? 我们知道Context的实现类为ContextImpl,所以我们进入到ContextImpl的getSystemService(String name)方法中:

@Override
public Object getSystemService(String name) {return SystemServiceRegistry.getSystemService(this, name);
}

这里执行了SystemServiceRegistry.getSystemService(String name)方法,继续跟踪该方法:

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

可以看到系统服务中介类是从ServiceFetcher.getService(ContextImpl ctx)方法获取的,而ServiceFetcher对象由SYSTEM_SERVICE_FETCHERS生成。SYSTEM_SERVICE_FETCHERS是一个HashMap,其Key为系统服务名,Value为ServiceFetcher对象。 那我们找一下SYSTEM_SERVICE_FETCHERS是什么时候被赋值的?在SystemServiceRegistry的registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher)方法中我们找到了:

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    //在这类SYSTEM_SERVICE_FETCHERS被赋值
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

再看registerService方法是什么时候被调用的?可以找到在SystemServiceRegistry类的静态代码块中调用了registerService方法:

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

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

    registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
            new CachedServiceFetcher<AccountManager>() {
        @Override
        public AccountManager createService(ContextImpl ctx) throws ServiceNotFoundException {
            IBinder b = ServiceManager.getServiceOrThrow(Context.ACCOUNT_SERVICE);
            IAccountManager service = IAccountManager.Stub.asInterface(b);
            return new AccountManager(ctx, service);
        }});

    registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
            new CachedServiceFetcher<ActivityManager>() {
        @Override
        public ActivityManager createService(ContextImpl ctx) {
            return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
        }});

    registerService(Context.ALARM_SERVICE, AlarmManager.class,
            new CachedServiceFetcher<AlarmManager>() {
        @Override
        public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {
            IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);
            IAlarmManager service = IAlarmManager.Stub.asInterface(b);
            return new AlarmManager(service, ctx);
        }});
        ...省略
}

这里多次调用了registerService方法,每一个registerService方法的参数中都new了一个ServiceFetcher对象。还记得上面我们说到的系统服务中介类是怎么来的吗?没错,就是通过ServiceFetcher对象的getService(ContextImpl ctx)获取的。而ServiceFetcher是一个接口,其getService(ContextImpl ctx)方法由子类来实现。在子类的实现方法中getService(ContextImpl ctx)方法又调用了createService(ContextImpl ctx)方法并返回,所以createService(ContextImpl ctx)方法生成的对象就是我们需要获取的服务中介类。

最开始的时候我们提到,服务中介类只是对系统服务的一个封装。那就表明在ServiceFetcher对象的createService(ContextImpl ctx)方法中肯定是能获取系统服务对象的。让我们看一个具体的例子:

registerService(Context.ALARM_SERVICE, AlarmManager.class,
        new CachedServiceFetcher<AlarmManager>() {
    @Override
    public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {
        IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);
        IAlarmManager service = IAlarmManager.Stub.asInterface(b);return new AlarmManager(service, ctx);
    }});

上面是获取闹钟系统服务的一个例子。 第一步: 通过ServiceManager.getServiceOrThrow(String name)获取了服务端的Binder对象,而getServiceOrThrow最终调用的还是getService(String name)方法:

public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);if (service != null) {
            return service;
        } else {
            return Binder.allowBlocking(getIServiceManager().getService(name));
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

上面的代码告诉我们,如果有缓存则从缓存获取服务端的Binder对象,如果没有则调用getIServiceManager().getService(String name)获取服务端的Binder对象:

private static IServiceManagergetIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

从上面的代码可以看到获取服务端Binder对象也是通过Binder对象进行跨进程通信获取的(IServiceManager是一个Binder对象)。

第二步: 通过调用IAlarmManager.Stub.asInterface(Binder binder)方法将第一步获取到的Binder对象转换成所需的系统服务对象。 这里说明一下,这个方法是区分进程的,如果客户端和服务端位于同一个进程,则返回服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy对象(该对象作为代理对象,与服务端进行通信并将数据返回给客户端)。

ServiceManager在这里起到的作用是对所有的系统服务进行管理,其提供了getService(String name)addService(String name)checkService(String name)listServices(String name)等方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值