浅谈Android java层ServiceManager

概述

ServiceManager作为Android进程间通信binder机制中的重要角色,运行在native层,由c++语言实现,任何Service被使用之前,例如播放音乐的MediaService,例如管理activity的ActivityManagerService,均要向SM注册,同时客户端使用某个service时,也需要向ServiceManager查询该Service是否注册过了。

ServiceManager作用

1、负责与Binder driver通信,维护一个死循环,不断地读取内核binder driver。即不断读取看是否有对service的操作请求。
2、维护一个svclist列表来存储service信息。
3、向客户端提供Service的代理,也就是BinderProxy。
延伸:客户端向ServiceManager查找Service并获取BinderProxy,通过BinderProxy实现与Service端的通信。
4、负责提供Service注册服务
其实,ServiceManager就像是一个路由,首先,Service把自己注册在ServiceManager中,调用方(客户端)通过ServiceManager查询服务

    它的实现是service_manager.c。而java中的ServiceManager.java仅仅是service_manager.c的封装。这里,我们不讨论service_manager.c是如何向下与Binder driver通信的,也不讨论注册、查找service的具体逻辑。而是从java层面,也就是Android FrameWork层面讨论是如何使用ServceManager.java服务的。

   ServiceManager.java的源码很简单,如下:

public final class ServiceManager {
    private static final String TAG = "ServiceManager";

    private static IServiceManager sServiceManager;
    private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();

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

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

    /**
     * Returns a reference to a service with the given name.
     * 
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn't exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     * 
     * @param name the name of the new service
     * @param service the service object
     */
    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     * 
     * @param name the name of the new service
     * @param service the service object
     * @param allowIsolated set to true to allow isolated sandboxed processes
     * to access this service
     */
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }
    
    /**
     * Retrieve an existing service called @a name from the
     * service manager.  Non-blocking.
     */
    public static IBinder checkService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().checkService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in checkService", e);
            return null;
        }
    }

    /**
     * Return a list of all currently running services.
     * @return an array of all currently running services, or <code>null</code> in
     * case of an exception
     */
    public static String[] listServices() {
        try {
            return getIServiceManager().listServices();
        } catch (RemoteException e) {
            Log.e(TAG, "error in listServices", e);
            return null;
        }
    }

    /**
     * This is only intended to be called when the process is first being brought
     * up and bound by the activity manager. There is only one thread in the process
     * at that time, so no locking is done.
     * 
     * @param cache the cache of service references
     * @hide
     */
    public static void initServiceCache(Map<String, IBinder> cache) {
        if (sCache.size() != 0) {
            throw new IllegalStateException("setServiceCache may only be called once");
        }
        sCache.putAll(cache);
    }
}

有如下功能

1、提供addService()方法,向native层注册服务

2、提供getService()方法,从native层获取服务

3、维护了缓存Map

    其实getService()就是从native层获取Binder,获取后通过Stub.asInterface()方法转化为BinderProxy,通过BinderProxy就可以通过其调用远端方法了。这部分知识我们是比较熟悉的,在通过AIDL自定义Service时,用到的就是这部分知识。这里我们先认为native层对我们是不透明的,只要了解到通过addService()和getService()就可以向native注册服务或从native层获取服务。想了解native是如何实现注册和获取服务的同学可以看这两篇文章:

Android Framework学习(十)之向ServiceManager注册Native层服务

Android Framework学习(十一)之从ServiceManager获取Native层服务

我们这里暂时不讨论

App端

从本人总结的的上一篇文章Android SystemServer解析中我们可以了解到,通过getSystemService()获取远端服务代理时,最终是通过ServiceFetcher.createService()方法创建XXManager,XXManager中封装了用于访问远端服务的BinderProxy,那么,这里我们探究下XXManager中的BinderProxy是如何而来的。其实我们猜也能猜到一定是通过ServiceManager.getService()获取的,我们来证实这一过程。

先挑一个最常用的ActivityManager,ActivityManager封装了对远端访问的业务方法,那么在这些方法中必然是通过调用BinderProxy来实现的,我们举两个例子:

    @Deprecated
    public List<RunningTaskInfo> getRunningTasks(int maxNum)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().getTasks(maxNum, 0);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
可以看到是通过调用ActivityManagerNative.getDefault().getTasks()方法,说明ActivityManagerNative.getDefault()返回的

BinderProxy,我们跟进去看:

ActivityManagerNative.getDefault()

/**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

看看getDefault()是什么:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

果不其然,是从ServiceManager中获取的IBinder,并转换为BinderProxy。

再看一个XXManager,BluetoothManager,其中有一个逻辑方法getConnectedSevices()如下:

public List<BluetoothDevice> getConnectedDevices(int profile) {
        if (DBG) Log.d(TAG,"getConnectedDevices");
        if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
            throw new IllegalArgumentException("Profile not supported: " + profile);
        }

        List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();

        try {
            IBluetoothManager managerService = mAdapter.getBluetoothManager();
            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
            if (iGatt == null) return connectedDevices;

            connectedDevices = iGatt.getDevicesMatchingConnectionStates(
                new int[] { BluetoothProfile.STATE_CONNECTED });
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }

        return connectedDevices;
    }

可以看到是通过mAdapter获取IBluetoothManager接口,也就是BinderProxy,跟进去BluetoothAdapter:

/*package*/ IBluetoothManager getBluetoothManager() {
            return mManagerService;
    }

返回mManagerService,该变量是构造BluetoothAdapter时传入的,发现BluetoothAdapter中包含创建BluetoothAdapter的方法getDefaultAdapter,如下:

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;
    }

可以看到,也是通过ServiceManager.getService()获取IBinder,并通过adInterface(b)方法转换为BinderProxy。

当然并不是所有的XXManager都需要远端服务,有些XXManager的业务方法是通过ContentProvider来实现的。

由此,我们验证了一点:XXManager中包含的BinderProxy是从ServiceManager.getService()获取的并通过asInterface()得到的。

SystemServer端

下面,我们再来验证注册服务是通过ServiceManager.addService()实现的,从上一篇文章Android SystemServer解析,我们得知,各中XXManagerService都是通过SystemServer.java的静态代码块创建并调用onStart()方法启动,看起来并没有和ServiceManager.addService()发生联系,不急,我们可以看到SystemServer.startOtherService()方法中存在如下代码:

telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);

可以发现就是通过ServiceManager.addService()向native注册服务

同时,在AMS中也可以发现注册核心Service的代码:

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));

说是注册Service,其实就是注册一个IBinder,该IBinder标明了自己的身份,我们可以发现addService()的第二个参数的类均是Binder,如VibratorService:

public class VibratorService extends IVibratorService.Stub
        implements InputManager.InputDeviceListener {
....

如TelephonyRegistory:

class TelephonyRegistry extends ITelephonyRegistry.Stub {
    private static final String TAG = "TelephonyRegistry";
.....

另外,XXManagerService的父类SystemService中,也提供了向ServiceManager注册的方法:

    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值