系统服务中的Binder对象

  摘自:柯元旦的《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 系统服务一览表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值