SystemServer进程源码分析之二

1, 基本概念

SystemServer进程中启动了大量的系统服务,有的服务可以被第三方apk获取并进行跨进程调用,有的只能在SystemServer进程中使用(也成为本地服务)。

2, 跨进程调用服务

以BluetoothService服务为例说明被第三方apk获取并进行跨进程调用的原理。

ServiceManager:管理所有服务,主要是注册和获取,并且单独运行在一个进程中,通过init启动。

2.1 注册

注册流程图如下,


SystemServer的startOtherServices方法中,

mSystemServiceManager.startService(BluetoothService.class);


@SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            •••
        }
        return startService(serviceClass);
}

@SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + name);
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
        }
        // Register it.
        mServices.add(service); // 添加到list中,便于管理
        // Start it.
        try {
            service.onStart(); // 注册
        } catch (RuntimeException ex) {
        }
        return service;
    }
public void onStart() {
      Log.d(TAG, "onStart: publishing BluetoothManagerService");
     publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);
    }

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

代码不是很难,但是要注意以下几点:

1,注册服务是为了其他进程获取服务并且使用服务,注册服务就像开了一个带锁的房间,使用该房间必须拥有对应的钥匙。在上面的例子中:

注册蓝牙服务时,钥匙为String类型的BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE

 

BluetoothAdapter.java中,该字符定义如下:

public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";

2.2 获取

再看使用该钥匙获取蓝牙服务

public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
            if (b != null) {
                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
                sAdapter = new BluetoothAdapter(managerService);
            } else {
                Log.e(TAG, "Bluetooth binder is null");
            }
        }
        return sAdapter;
    }

2,真正获取的服务是 BluetoothManagerService 而非 BluetoothService

3,注册和获取服务远远不止这么简单,因为服务和服务管理分属于不同进程,所以还涉及到进程间通信机制,在这里就不详细的说Binder通信机制了。

3, 本地服务

以LightsService服务为例说明本地服务。

本地服务的启动流程和上面的注册流程相差无几,只是在LightsService的onStart方法中调用的是publishLocalService方法,

@Override
    public void onStart() {
        publishLocalService(LightsManager.class, mService);
    }

父类SystemService的publishLocalService方法如下,

protected final <T> void publishLocalService(Class<T> type, T service) {
        LocalServices.addService(type, service);
    }

LocalServices的addService方法如下,

public static <T> void addService(Class<T> type, T service) {
        synchronized (sLocalServiceObjects) {
            if (sLocalServiceObjects.containsKey(type)) {
                throw new IllegalStateException("Overriding service registration");
            }
            sLocalServiceObjects.put(type, service);
        }
    }

sLocalServiceObjects是一个map,定义如下,

private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
            new ArrayMap<Class<?>, Object>();

android系统中本地服务如下(android 版本不同,可能稍微不一样,这是android 6.0),

UsageStatsService

NotificationManagerService

PowerManagerService

DeviceStorageMonitorService

BatteryService

LightsService

DreamManagerService

DisplayManagerService

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值