Android Application Framework Outside, Service Understanding : 4

这是一篇旧文了,写于二零一零年七月至九月期间。当时我正在OPPO,完了电纸书项目,刚刚转入公司战略级项目,受命专职钻研Android Framework。本文即为当时的工作成果,曾以此为蓝本,组织了内部培训。本文成文后半月,我因不可抗拒原因,离开了OPPO,对Framework的研究中断,遂失去了一次专心研究Android的良机,深感痛惜。今日我把它晒出来,一来是温故旧知,二来帮助他人,但受限于既有知识,对Android的理解依旧是囫囵吞枣,文中谬误之处再所难免,恳请读者指正。

Contents

  1. Forward
  2. Android Startup
  3. Service Overview
    1. Application Service
    2. Android Service
    3. Native Service
    4. System (Linux) Service
  4. Manage Service
    1. Manage Android Service
    2. Behind ServiceManager Class
    3. Manage Native Service
    4. Behind defaultServiceManager
  5. Inter Process Communication
    1. From Java to Native
    2. What’s BpBinder
    3. What’s BBinder

Inter Process Communication

在上文当中提到的service命令,它是如何获得服务的信息呢?这个这个仅为275行的简单程序(framework/base/cmds/service/service.cpp)并未有什么特别神奇的地方,从本质上它对服务信息一无所知,所有的信息都是通过IPC获得。

IPC(Inter Process Communication)几乎总是伴随着Service出现,–不论是系统服务,还是应用服务,因为服务运行的进程大部分和应用运行的进程不同。

Android有意淡化IPC,甚至使其透明,就连Android Dev Guide也只是对IPC只做简明的解释说明,Android这样做的目的是降低应用开发的技术门槛,使开发者更多关注业务逻辑等商业价值点。

注意:RPC的全称为Remote Procedure Call,虽然和IPC只有一字之差,但并不相同。

IPC只是一种概念,实现IPC的方式有多种,例如在linux上你可以使用socket等,而Android中则采用了Binder。

From Java to Native

图表19展现的是ServiceManagerNative等相关类的结构,IPC/Binder的影子出现在了最后的位置。

那么Binder又是怎么样实现IPC呢?任何试图用一个模糊、新颖的概念来解释原有问题的行为,是一种混淆视听、忽悠人的伎俩,这不是探求真知的的态度。由于Service Manager本身也是一种服务,也是使用IPC的实例之一,以下就以Service Manager为例来进行追踪。

图表 19

图表20是Servcei Manager的C++层相关类的类图(Class Diagram)。

图表 20

从图表20可以看出,B(n)ServiceManager和BpServiceManager都是IServiceManager的子类。BpServiceManager是为在被调用时准备的代理对象,而BServiceManager则是真正的实现对象。

图表 21 (frameworks/base/cmd/runtime/ServiceManager.cpp)

图表21展现的是实现添加服务的真实实现代码。当系统将IPC请求分发给实现对象时,首先是通过BBinder的transact方法,然后转发给实现对象的onTransact方法。

What’s BpBinder

IBinder是对跨进程对象的抽象,在Android中代码注释是这样描述的:

(IBinder is) Base class and low-level protocol for a remotable object. You can drive from this class to create an object for which processes can hold references to it. Communication between processes (method calls, property get and set) is down through a low-level protocol implemented on top of the transact() API.

IBinder当中有一个关键的函数即transact,如图表22所示。

图表 22(frameworks/base/include/binder/IBinder.h)

通过图表20可以知道,BpBinder是IBinder的子类,那么BpBinder是怎样实现这个方法的呢?

图表 23(frameworks/base/libs/binder/BpBinder.cpp)

通过图表23可以知道,BpBinder实际上调用了IPCThreadState的transact方法。

What’s BBinder

IBinder的另一个子类为BBinder,那么它的transact方法又是怎么样的呢?如图表24所示。

图表 24(frameworks/base/libs/binder/Binder.cpp)

从上面可以看出transact实际上也没有完成多少工作,其把核心的操作留给了onTransact方法去做,虽然BBinder类实现了onTransact,但实际上这个方法是一定要被子类重写(override)的。例如,在图表20中,BBinder的子类BnServiceManager是这样重写该方法的 。

图表 25(frameworks/base/libs/binder/IServiceManager.cpp)

由此可以知道,服务真正实现代码是在BBinder的子类中,这才是真正做事的角色,而BpBinder则只是一个代理角色,–这也难怪其名称中带有一个p,大概就是Proxy的意思吧。


到此为止,全文结束。可以坦诚地讲,这篇博文是不完整的,并没有将Service解释清楚,希望自己以后能有机会完善这部分的知识。再次声明,本文只供参考,不做权威性解读。

Leave a comment

Your comment