概述

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 sCache = new HashMap();    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 null 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 null 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 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 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 gDefault = new Singleton() {        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 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 connectedDevices = new ArrayList();        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);    }

更多相关文章

  1. ANDROID STUDIO&&Eclipse Android项目缺少R文件解决方法(完解)
  2. android中WebView的Java与JavaScript交互
  3. 《第一行代码》 6.3 SharedPreferences存储
  4. Android(java)同步方法synchronized
  5. Android——RecyclerView入门学习之LayoutManager
  6. Android(安卓)通用获取Ip的方法(判断手机是否联网的方法)!!!
  7. Content Provider使用方法以及Android运行时权限申请
  8. Android心得2.4--四大组件之一--Activity
  9. Webkit for Android分析

随机推荐

  1. Android(安卓)发送邮件 JavaMail
  2. Android sdk更新代理配置
  3. Android - 自定义Dialog内部透明,外部有遮
  4. Android中线程池的分类
  5. android 下Excel操作
  6. android studio 2.1.1 启动abd出错
  7. Android Wifi框架流程分析
  8. Android——分别获取导航栏、状态栏高度
  9. android 判断网络是否可用,并调用系统设置
  10. Android中的bitmap,drawable,canvas以及pai