Android SystemService 源码解析

Android SystemService 源码解析

基于Api 28 源码

Android Framework 层两大非常重要的进程:

  • SystemServer
  • zygote进程

SystemServer 是由 zygote 进程 fork 出来的一个单独的进程。

系统里面重要的服务都是在这个进程里面开启的,比如 ActivityManagerService(AMS)PackageManagerService(PMS)WindowManagerService(WMS) 等等。

它们是怎么启动起来的?

AMS、PMS 之类的 Servie 是怎么注册的?

一、AIDL 手写 SystemService 源码

SystemServer 是一个单独的进程,跟其他进程进行通讯使用 AIDL,所以离不开 Binder 的使用。

为了更好的理解源码,先新建一个工程,模仿 SystemServer 源码,手写 SystemServer 源码。

步骤如下:

  1. 找到Framework层源码 IServiceManager.java
  2. 复制到自己的 Android Studio 工程,创建 IServiceManager.aidl
  3. 使用中Android Studio 自动生成AIDL文件,IServiceManager.java
  4. 跟 Android源码 一样创建自己的 ServiceManager 管理类:ServiceManager.java
  5. 跟系统一样使用:AidlActivity.java
源码 ServiceManagerNative ServiceManagerNative#ServiceManagerProxy
手写 IServiceManager#Stub#Proxy IServiceManager#Stub#Proxy

读源码之前先看下这个简单的工程,非常有助于理解SystemServer 源码。

Android SystemService 源码解析_第1张图片
image

二、 系统服务启动的两种方式

  • ServiceManager 的 addService()
  • SystemServiceManager 的 startService()

两种方式最后都会采用 ServiceManager.addService() 方法。

Android SystemService 源码解析_第2张图片
image

三、核心类

  • SystemServer

    SystemServerZygote fork生成的,进程名为 system_server,该进程承载着 framework 的核心服务。

  • SystemService

    系统服务类的抽象基础类。

  • ServiceManagerNative

    SystemService 的 AIDL 类。

  • ServiceManagerNative#ServiceManagerProxy

    SystemService 的AIDL客户端代理类,ServiceManagerProxyServiceManagerNative 的内部类。

  • ServiceManager

    ServiceManagerNative 的管理类,封装了 ServiceManagerNative ,使用 addService() 来启动服务

  • SystemServiceManager

    注册服务的另一种方式,通过 startService() 来启动服务

四、系统服务启动入口

// SystemServer.java
private void run(){
        //···
    traceBeginAndSlog("StartServices");
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    SystemServerInitThreadPool.shutdown();
    //···
}

run() 方法中启动系统服务、核心服务、其他服务。

五、ServiceManager.addService 方式

执行流程:

Android SystemService 源码解析_第3张图片
image

这里以 NetworkStatsService 服务为例, 说明这类服务的启动方式:

public class NetworkStatsService extends INetworkStatsService.Stub{}

//StartNetworkStatsService
networkStats = NetworkStatsService.create(context, networkManagement);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);

5.1 ServiceManager.addService

    //ServiceManager.java
    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

5.2 ServiceManager.getIServiceManager

   // ServiceManager.java
   private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }
        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

采用了单例模式获取ServiceManagergetIServiceManager() 返回的是 ServiceManagerProxy 对象.

BinderInternal.getContextObject() 是一个 native 方法,返回一个 IBinder 对象。

public class BinderInternal {
    /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();
}

5.3 ServiceManagerNative.asInterface

左侧为api 28 源码,右侧为自己手写项目中的类。

Android SystemService 源码解析_第4张图片
image

从上图可知:aiInterface() 方法跟自己在项目中Android Studio 自动生成的代码基本一样。如果是同一个进程,返回当前对象;如果是跨进程调用,返回一个 ServiceManagerProxy 代理对象。

如果 Service 运行在同一个进程,那就直接用 Stub(ServiceManagerNative),因为它直接实现了 Service 提供的功能,不需要任何 IPC 过程。如果 Service 运行在其他进程,那客户端使用的就是 Proxy(ServiceManagerProxy), Proxy 就是把参数封装后发送给 Binder 驱动,然后执行一系列 IPC 操作最后再取出结果返回。

5.4 ServiceManagerProxy创建

左侧为api 28 源码,右侧为自己手写项目中的类。

Android SystemService 源码解析_第5张图片
image

ServiceManagerProxyServiceManagerNative的内部类。

ServiceManagerProxy 就是 CS 架构中的 Client 端。

5.5 ServiceManagerProxy.addService

public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    data.writeStrongBinder(service);
    data.writeInt(allowIsolated ? 1 : 0);
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
}

ServiceManagerProxy 通过 mRemote.transact() 发起了标志位为 IServiceManager.GET_SERVICE_TRANSACTION请求,服务端中相应的响应线程就会通过 JNI 调用到 Stub 类, 在switch (code) 中根据标志位 IServiceManager.GET_SERVICE_TRANSACTION然后执行里面的 execTransact 方法,进而转到 onTransact()方法,通过 reply.writeStrongBinder(service)将数据抛送回去给客户端。

switch (code) {
        case IServiceManager.GET_SERVICE_TRANSACTION: {
        data.enforceInterface(IServiceManager.descriptor);
        String name = data.readString();
        IBinder service = getService(name);
        reply.writeStrongBinder(service);
        return true;
}

六、 SystemServiceManager.startService方式

以BatteryService 为例:

traceBeginAndSlog("StartBatteryService");
// Tracks the battery level.  Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
public final class BatteryService extends SystemService {}

6.1 SystemServiceManager.startService

    public SystemService startService(String className) {
        final Class serviceClass;
        try {
          //通过反射获取 Service的 Class 对象。
            serviceClass = (Class)Class.forName(className);
        } catch (ClassNotFoundException ex) {
                    //···
        }
        return startService(serviceClass);
    }
    public  T startService(Class serviceClass) {
        try {
            final String name = serviceClass.getName();
                //···
            // 判断启动的服务是否继承自 SystemService 抽象类
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
              //通过反射创建目标服务类的对象
                Constructor constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                            //···
            }
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
    public void startService(@NonNull final SystemService service) {
        //将该服务添加到 mServices,mService 是一个 ArrayList
        mServices.add(service);
        try {
        //执行服务的onStart过程,不同的服务有不同的实现
            service.onStart();
        } catch (RuntimeException ex) {
                //···
        }
    }

SystemServiceManager.startService 执行流程如下:

  1. 通过反射获取启动服务的 Class 对象。
  2. 判断启动的服务是否继承自 SystemService 抽象类。
  3. 通过反射创建目标服务类的对象。
  4. 将该服务添加到 mServices
  5. 执行服务的 onStart 过程,不同的服务有不同的实现。

看到这并没有看到服务是如何注册到 ServiceManager , 这里继续以BatteryService 为例,那肯定就是在子类的 onStart() 完成.

6.2 BatteryService.onStart

    @Override
    public void onStart() {
        registerHealthCallback();
        mBinderService = new BinderService();
        publishBinderService("battery", mBinderService);
        mBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();
        publishBinderService("batteryproperties", mBatteryPropertiesRegistrar);
        publishLocalService(BatteryManagerInternal.class, new LocalService());
    }
    private final class BinderService extends Binder {
        //···
    }
    private final class BatteryPropertiesRegistrar extends IBatteryPropertiesRegistrar.Stub{
      //···
    }

BinderServiceBatteryService 的内部类,继承自 Binder。

BatteryPropertiesRegistrar 也是 BatteryService 的内部类,继承自Stub,Stub 也是继承自 Binder。

6.3 SystemService.publishBinderService

    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }

跟第一种方式一样,同样也是采用 ServiceManager.addService() 方法。

跟第一种方式不同的是,这种方式会把 Service 添加到 SystemServiceManagermServices 中。

mServices 是一个 SystemService 的 List 集合,属于SystemServiceManager 成员变量,接收 lifecycle event 的回调。通过循环遍历 mServices ,来执行集合中每个SystemService子类对应的方法。

类似的方法有:

  • startBootPhase()
  • startUser()
  • unlockUser()
  • switchUser()
  • stopUser()
  • cleanupUser()

举例 onSwitchUser()

    public void switchUser(final int userHandle) {
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            try {
                service.onSwitchUser(userHandle);
            } catch (Exception ex) {
               // ···
            }
        }
    }
//SystemService.java
/**
 * Called when switching to a different foreground user, for system services that have
 * special behavior for whichever user is currently in the foreground.  This is called
 * before any application processes are aware of the new user.
 * @param userHandle The identifier of the user.
 */
public void onSwitchUser(int userHandle) {}

从方法注释可以知道,onSwitchUser() 跟多用户切换有关系。

七、 总结

方式1. ServiceManager.addService():
  • 功能:向ServiceManager注册该服务.
  • 特点:服务往往直接或间接继承于Binder服务;
  • 举例:InputManagerService 、WindowManagerService、PackageManagerService
方式2. SystemServiceManager.startService:
  • 功能:
    • 创建服务对象;
    • 执行该服务的onStart()方法;该方法会执行上面的ServiceManager.addService();
    • 根据启动到不同的阶段会回调onBootPhase()方法;
    • 多用户模式下用户状态的改变也会有回调方法;例如onSwitchUser();
  • 特点:服务往往自身或内部类继承于 SystemService;
  • 举例:StartBatteryService、ActivityManagerService;

两种方式最后都会执行到 ServiceManager.addService()

参考 Gityuan 博客

你可能感兴趣的:(Android SystemService 源码解析)