Framework篇 - 系统服务的注册方式

本文源代码基于 Android 7.0。 

有两种不同的方式来注册系统服务:

  • ServiceManager.addService()
  • SystemServiceManager.startService()

这两种方式最终都是向 service manager 进程注册 Binder 服务,但是在功能上有区别,下面从代码角度来分析。

 

 

1. ServiceManager.addService()

以 InputManagerService 为例。

 

  • 1.1 启动服务

/base/services/java/com/android/server/SystemServer.java

在 system server 启动时,会创建 InputManagerService 服务,并将其注册到 Service Manager 中。

private void startOtherServices() {
    // ...
    InputManagerService inputManager = null;
    inputManager = new InputManagerService(context);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
    inputManager.start();
    // ...
}
  • 1.2 ServierManager.addService()

/base/tools/layoutlib/bridge/src/android/os/ServiceManager.java

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

        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

采用了 getIServiceManager() 返回的是 ServiceManagerProxy 对象。

 

  • 1.3 ServiceManagerNative

/base/core/java/android/os/ServiceManagerNative.java

    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        // 由于obj为BpBinder,该方法默认返回null
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj);
    }

这边返回的是 ServiceManagerProxy 对象,addService() 经过 IPC 最终到达 ServiceManagerNative 的 onTransaction():

            case IServiceManager.ADD_SERVICE_TRANSACTION: {
                data.enforceInterface(IServiceManager.descriptor);
                String name = data.readString();
                IBinder service = data.readStrongBinder();
                boolean allowIsolated = data.readInt() != 0;
                addService(name, service, allowIsolated);
                return true;
            }
    

最终进入 service manager 进程,具体可以参考:Framework篇 - ServiceManager 注册和获取服务

 

 

2. SystemServiceManager.startService()

通过这种方式启动的服务,有一个特点都是继承于 SystemService 类,比如 JobSchedulerService。

 

  • 2.1 启动服务

/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {
    // ...
    mSystemServiceManager.startService(JobSchedulerService.class);
    // ...
}
  • 2.1 JobSchedulerService

/base/services/core/java/com/android/server/job/JobSchedulerService.java

public final class JobSchedulerService extends com.android.server.SystemService
        implements StateChangedListener, JobCompletedListener {
}

可以看到,它继承于 SystemService 类。

 

  • 2.2 SystemServiceManager.startService()

/base/services/core/java/com/android/server/SystemServiceManager.java

    @SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        // 采用反射
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
        }
        return startService(serviceClass);
    }

    @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            final T service;
            try {
                // 构造出Service对象
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
            } 

            // 添加到ArrayList<SystemService>中
            mServices.add(service);
            try {
                // 调用Service的onStart方法
                // 看到这并没有看到服务是如何注册到ServiceManager, 其实是在 service 的 onStart() 中完成
                service.onStart();
            } catch (RuntimeException ex) {            
            }
            return service;
        } finally {
        }
    }

注意上面,有个 mService 对象,是一个 SystemService 的集合,两种注册服务的方式区别就在于它,后面会讲。

 

  • 2.3 JobSchedulerService.onStart()

/base/services/core/java/com/android/server/job/JobSchedulerService.java

注册服务是在 onStart() 中,看看 JobSchedulerService 的 onStart():

    @Override
    public void onStart() {
        publishLocalService(JobSchedulerInternal.class, new LocalService());
        publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub);
    }

 

  • 2.4 SystemService.publishBinderService()

/base/services/core/java/com/android/server/SystemService.java

publishBinderService() 定义在  JobSchedulerService 的父类 SystemService 中:

    protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }

    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        // 最终还是调用了ServiceManager的addService函数来注册服务
        // 通过这种方式启动的服务, 都是继承于SystemService类, 那么这种方式启动的服务有什么特殊之处吗? 答应就是startBootPhase的过程:
        ServiceManager.addService(name, service, allowIsolated);
    }

可以看到,最终还是调用了 ServiceManager.addService()。 

 

 

3. 两种方式的区别

SystemServiceManager 中有一个 ServiceManager 的集合,每通过它注册一个服务,便会将该服务放到集合中。看看 SystemServiceManager 的 startBootPhase():

    // 所有通过该方式注册的继承于SystemService的服务,都会被添加到mServices.
    // 该方法会根据当前系统启动到不同的阶段, 则回调所有服务onBootPhase()方法
    public void startBootPhase(final int phase) {
        mCurrentPhase = phase;

        try {
            final int serviceLen = mServices.size();
            for (int i = 0; i < serviceLen; i++) {
                final SystemService service = mServices.get(i);
                try {
                    service.onBootPhase(mCurrentPhase);
                } catch (Exception ex) {
                    // ...
                }
            }
        } finally {
        }
    }

系统开机启动过程,当执行到 system_server 进程时,将启动过程划分了几个阶段,定义在 SystemService.java 文件中:

    /*
     * Boot Phases
     */
    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?

    /**
     * After receiving this boot phase, services can obtain lock settings data.
     */
    public static final int PHASE_LOCK_SETTINGS_READY = 480;

    /**
     * After receiving this boot phase, services can safely call into core system services
     * such as the PowerManager or PackageManager.
     */
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    /**
     * After receiving this boot phase, services can broadcast Intents.
     */
    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    /**
     * After receiving this boot phase, services can start/bind to third party apps.
     * Apps will be able to make Binder calls into services at this point.
     */
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

    /**
     * After receiving this boot phase, services can allow user interaction with the device.
     * This phase occurs when boot has completed and the home application has started.
     * System services may prefer to listen to this phase rather than registering a
     * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
     */
    public static final int PHASE_BOOT_COMPLETED = 1000;

PHASE_BOOT_COMPLETED=1000,该阶段是发生在 Boot 完成和 home 应用启动完毕,对于系统服务更倾向于监听该阶段,而非监听广播 ACTION_BOOT_COMPLETED。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值