你好,游客 登录 注册 搜索
背景:
阅读新闻

Android之Binder设计分析

[日期:2012-07-24] 来源:Linux社区  作者:a2758963 [字体: ]

接着上篇binder简要介绍(见 http://www.linuxidc.com/Linux/2012-07/66195.htm ),我们来分析binder机制的设计。binder主要框架分为三个部分:服务端,binder驱动,客户端。

binder在Android最常见的使用场景就是一个程序的activity与系统service进行交互。比如我通过wifi的service来获取wifi控制代理对象,来对wifi进行相关的操作。注意:这里的系统service是指System server,而不是sdk 中的Service类。

从Linux空间上来看,Activity,系统service它们都分属不同的进程,不同进程之间的数据交换就是涉及到了IPC通信。而如果我们从开发者调用角度来看,我们看不到进程的概念。从公共对象请求代理的高度来看Binder,我们会惊异于这种设计思路。Binder相对于Activtiy,service来说是一个很低层的概念。当设计android程序涉及到IPC,我们无需考虑底层的实现细节,而去只关心怎么去获取相关服务并通信,这也使我们更专注于软件的开发,而非传统基于C/S架构去思考它们之间的数据是如何去实现交换的。

在用户空间,我们需要做的就是去请求相关有能力的服务对象,不必去了解这个通讯是如何完成。这种设计架构给不仅解决了通讯,引入了一种新的设计理念,也与java面向对象的开发思想契合在一起。这里,我们看不到binder,我们感觉就像是客户端直接身服务端请求,然后通过服务端的一个代理对象处理相关工作。Activity与service之间仿佛是一种很直接的,自然的通信。

对于android外部性空间来说,我们不知道服务对象在哪里,我们只需通过公共代理对象去请求服务。Android系统中,系统级的service都是由serviceManager来管理。借着serviceManger就可以获取service的对象引用。

先了解下serviceManger,它本身也是一个service,但它管理着系统其它的service。Framework提供了一个系统函数BinderInternal.getContextObject(),可以获取该Service对应的Binder引用。通过这个静态函数返回的ServiceManager提供的方法又可以获取其它系统Service的Binder引用。所以serviceManager是整个系统service的总管,也是系统的一个核心对象,它是开机就自启动的。其它的service都要向它进行注册并保管引用,这样保证所有的服务都可以通过servericeManger获取到引用。这种设计模式的一个好处就是仅暴露一个Binder引用,而其它的系统服务可以隐藏起来,从而有助于系统服务的扩展,以及调用系统服务的安全检查 。现在我们来看下serviceManger是怎样处理service的注册和查询的。我先看下serviceManger源码:

在源码里有一个HashMap,HashMap里保存着系统service的名字,和引用。

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

继续看源码了解客户端向服务的请求是怎样完成的:在客户端通过ServiceManager类getService(String name)方法传递一个需要的服务,然后ServcieManager在sCache的HashMap中去查询与name对应的service,然后再将这个service的IBinder引用返回给客户端。

  1. public static IBinder getService(String name) {  
  2.          try {  
  3.              IBinder service = sCache.get(name);  
  4.              if (service != null) {  
  5.                  return service;  
  6.              } else {  
  7.                  return getIServiceManager().getService(name);  
  8.              }  
  9.          } catch (RemoteException e) {  
  10.              Log.e(TAG, "error in getService", e);  
  11.          }  
  12.          return null;  
  13.      }  
linux
相关资讯       Binder 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款