您的位置:首页 > 其它

系统服务中的Binder对象

2014-09-05 17:14 183 查看
  摘自:柯元旦的《Android内核剖析》

 系统服务中的Binder对象

 在应用程序编程时,经常使用getSystemService(String serviceName)方法获取一个系统服务,那么,这些系统服务的Binder引用是如何传递给客户端的呢?须知系统服务并不是通过startService()启动的。

  getSystemService()函数的实现是在ContextImpl类中,该函数所返回的Service比较多,这些Service一般都由ServiceManager管理。
1. ServiceManager管理的服务

 ServiceManager是一个独立进程,其作用是管理各种系统服务。
 ServiceManager本身也是一个Service,Framework提供了一个系统函数,可以获取该Service对应的Binder引用,那就是BinderInternal.getContextObject().该静态函数返回ServiceManager后,就可以通过ServiceManager提供的方法获取其它系统Service的Binder引用。这种设计的好处是系统中仅暴露一个全局Binder引用,那就是ServiceManager,而其他系统服务则可以隐藏起来,从而有助于系统服务的扩展。其他系统服务在启动时,首先把自己的Binder对象传递给ServiceManager,即所谓的注册(addService).

  下面从代码实现来看以上的逻辑,可以查看ContextImpl.getSystemService()中各种Service的具体获取方式,比如INPUT_METHOD_SERVICE,代码如下:

else if(INPUT_METHOD_SERVICE.equals(name)){

    return InputMethodManager.getInstance(this);

}

而InputMethodManager.getInstance(this)的关键代码如下:
synchronized(mInstanceSync){
if(mInstance!=null){
return mInstance;
}
IBinder b=ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
IInputMethodManager service=IInputMethodManager.Stub.asInterface(b);
mInstance=new InputMethodManager(service.mainLooper);
}
return mInstance;
  即通过ServiceManager获取InputMethodService对应的Binder对象b,然后再将该Binder对象作为IInputMethodManager.Stub.asInterface()的参数,返回一个IInputMethodManager的统一接口。

  ServiceManager.getService()的代码如下:
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){
e.printStackTrace();
}
return null;
}
即首先从sCache缓存中查看是否有对应的Binder对象,有则返回,没有则调用getIServiceManager().getService(name),第一个函数getIServiceManager()即用于返回系统中唯一的ServcieManger对应的Binder,其代码如下:
private static IServiceManager getIServiceManager(){
if(sServiceManager!=null){
return sServiceManager;
}
sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
   以上代码中,BinderInternal.getContextObject()静态函数即用于返回ServiceManager对应的全局Binder对象。

  其他所有通过ServiceManager获取的系统服务的过程与以上基本类似,所不同的就是传递给ServiceManager的服务名称不同,因为ServiceManager正是按照服务的名称来保存不同的Binder对象。

2. 理解Manager

  ServiceManager所管理的所有Service都是以相应的Manager返回给客户端。在Android中,Manager应翻译为经纪人,Manager所manager的对象是服务本身,因为每个具体的服务一般都会提供多个API接口,而Manager所manager的正是这些API.客户端一般不能直接通过Binder引用去访问具体的服务,而是要经过一个Manager,相应的Manager类对客户端是可见的,而远程的服务类对客户端则是隐藏的。

    这些Manager类的内部都会有一个远程服务Binder的变量,而且在一般情况下,这些Manager的构造函数参数中会包含这个Binder对象。简单地讲,即先通过ServiceManager获取远程服务的Binder引用,然后使用这个Binder引用构造一个客户端本地可以访问的Manager,然后客户端就可以通过该manager访问远程的服务。

   这个设计的作用是屏蔽直接访问远程服务,从而可以给应用程序提供灵活的、可控的API接口,比如AmS.系统不希望用户直接去访问AmS,而是经过ActivityManager类去访问,而ActivityManager内部提供了一些更具可操作性的数据结构,比如RecentTaskInfo封闭了最近访问过的Task列表,MemoryInfo数据类封闭了和内存相关的信息。

   这种通过本地Manager访问远程服务的模型如图所示:

   

   


getSystemService(String name)是Android很重要的一个API,根据NAME来取得对应的Object,然后转换成相应的服务对象。以下介绍常用系统相应的服务。

name

返回的对象

说明 

WINDOW_SERVICE

WindowManager                     

管理打开的窗口程序

LAYOUT_INFLATER_SERVICE     

LayoutInflater                     

取得xml里定义的view

ACTIVITY_SERVICE               

ACTIVITY_SERVICE               

管理应用程序的系统状态

POWER_SERVICE                  

PowerManger                         

电源的服务

ALARM_SERVICE                   

AlarmManager                       

闹钟的服务

NOTIFICATION_SERVICE        

NotificationManager                

状态栏的服务

KEYGUARD_SERVICE             

KeyguardManager                   

键盘锁的服务

LOCATION_SERVICE              

LocationManager                    

位置的服务,如GPS

SEARCH_SERVICE                 

SearchManager                      

搜索的服务

VIBRATOR_SERVICE              

Vibrator                                 

手机震动的服务

CONNECTIVITY_SERVICE        

Connectivity                           

网络连接的服务

WIFI_SERVICE                      

WifiManager                           

Wi-Fi服务

TELEPHONY_SERVICE             

TeleponyManager                   

电话服务

更多可以查看这里:①Android常用系统服务   ②Android 系统服务一览表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: