本文以Android 5.1为例展开,在7.0上细节会略有差异,但基本一致:

Service大致分为两种

1. 系统服务SystemService

// 以下展示的框架为标准的Android SystemService的调用结构。如:Context.LOCATION_SERVICE. [services.jar部分]

  • 服务提供方通过ServiceManager.addService()注册服务

  • 服务调用方通过ServiceManager.getService()获取服务,为IBinder类型. (通常供framework.jar使用,framework.jar内部会再包装Wrapper类,最后供上层APP使用.)

[framework.jar部分]

  • 使用ContextImpl.registerService() (在7.0上为SystemServiceRegistry), 将通过ServiceManager.getService()的到的IBinder对象注册到framework中.

  • 在APP中使用context.getSystemService(LOCATION_SERVICE)

2. 普通APP的Binder服务 服务提供方在内部最终通过什么注册服务? (TODO: 分析如应用中的服务是如何注册的) 服务调用放通过bindService获得服务,为IBinder类型

以上两种方法对于IBinder都一样,使用asInterface将IBinder转为可方便调用的Client端接口:

    public static IPowerManager asInterface(IBinder arg2) {
        IPowerManager v1 = null;
        if(arg2 == null) {
            return v1;
        }

        IInterface v0 = arg2.queryLocalInterface("android.os.IPowerManager");
        if(v0 != null && ((v0 instanceof IPowerManager))) {
            return ((IPowerManager)v0);  // 如果该Service在本进程内,则直接返回。
        }

        return new Proxy(arg2);  // Service不在本进程内,使用Proxy进行代理访问(内部通过mRemote.transact()访问远端服务)。
    }

1个标准Android SystemService的完整实现

首先在services.jar中添加服务

在service.jar可以通过调用SystemService.publishBinderService()或ServiceManager.addService将1个Service加入Binder队列.

SystemManager.addService(LOCATION_SERVICE, new LocationManagerService(context));
// or
SystemService.publishBinderService(POWER_SERVICE, new BinderService(this, null));

最后在framework中使用ContextImpl.registerService()将包装Binder后的Wrapper对象加入队列,之后便可以在APP开发中直接使用context.getSystemService(XXXX_SERVICE)获取Manager(Wrapper)进行服务操作:

// xref: /frameworks/base/core/java/android/app/ContextImpl.java
 static {
      // 将对应Service的Manager(Wrapper)加入管理器中, 以后便可以直接在APP开发中使用context.getSystemService(XXXX_SERVICE)来获取指定服务的Manager(Wrapper).
    /////////////////////////////////////// LOCATION_SERVICE //////////////////////////////////////
    registerService(LOCATION_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(LOCATION_SERVICE);
                return new LocationManager(ctx, ILocationManager.Stub.asInterface(b)); 
            }});
    // ...
}

其它

addService / getService大致实现

// pos: framework.jar
package android.os;
public final class ServiceManager {
    // ...

    public static void addService(String arg3, IBinder arg4) {
        try {
            ServiceManager.getIServiceManager().addService(arg3, arg4, false);
        }
        catch(RemoteException v0) {
            Log.e("ServiceManager", "error in addService", ((Throwable)v0));
        }
    }

    public static IBinder getService(String arg5) {
        IBinder v4 = null;
        try {
            Object v1 = ServiceManager.sCache.get(arg5);
            if(v1 != null) {
                return ((IBinder)v1);
            }

            return ServiceManager.getIServiceManager().getService(arg5);
        }
        catch(RemoteException v0) {
            Log.e("ServiceManager", "error in getService", ((Throwable)v0));
            return v4;
        }
    }
    // ...
}

publishBinderService的实现

// pos: services.jar
package com.android.server;
public abstract class SystemService {
    // ...
    protected final void publishBinderService(String arg1, IBinder arg2, boolean arg3) {
        ServiceManager.addService(arg1, arg2, arg3);  // 最终会调入framework.jar中的android.os.ServiceManager
    }
    // ...
}