IPC(进程间通信),Remote Call(远程调用),IDL(接口描述语言)架构及其在BMP(BREW移动平台),Android中的应用浅析
由于本人才初识BMP和Android,所以仅仅是自己的一些肤浅认识,难免有错误,欢迎指正。
首先我们看IPC,现代操作系统都是多进程,多线程的。进程间存在地址边界,无法直接跨越。所以,两个进程间无法进行直接的请求,传递和调用。IPC是操作系统内核提供的一种跨进程的机制,允许两个进程间使用IPC来传递数据。 虽然某些情况下我们可以将Service直接加载到自己的进程中调用服务,此时可以进行简单的本地调用(Local Call),但是,从安全,性能和共享的角度出发,更多的情况下,Service都是运行在自己独立的进程中,此时Client使用其服务时,就必须跨越进程,那么就涉及到了IPC。 所以,在现代操作系统或者移动平台上,IPC是无处不在的。
IPC是操作系统层面提供的一种很底层的机制。你可以把它看做基础设施,传输媒介甚至底层协议。它只负责进程间传递数据,究竟数据是什么含义,发送,接收方如何处理这些数据等等都不是它的处理范围。 而这些,恰恰是上层需要为特定场景制定特殊的解决方案,框架,制定一致的规约,协议, 就像TCP/IP一致化了底层传输机制,但是面对不同应用场景的数据传输,必须由不同的应用层协议来协调C/S,以便能理解对应的语义,从而正常收发。 在非本地(同一进程内称之为本地)的复杂数据传递,调用中,尤其需要制定这样一套规则,来一致的解决问题。比如,远程对象调用。 Remote Call就是为此而生, 虽然初期其只应用在真正的两台主机间的远程调用,但目前,其思想已经应用在了任何非本地的服务调用中,比如,同一机器的两个不同进程间,同一机器的两个CPU间,两个机器的两个进程间。这是由于,其一致的解决框架可以屏蔽底层媒介(Inter Process, Inter Processor, Inter Machine)的差异性。 目前最典型的远程对象调用机制主要有 序列化对象(比如RMI) 和 基于远程代理的对象请求(如CORBA)
序列化对象方式
这种方式主要能够完成简单的单次对象远程传递。 将待传递的对象内存空间进行序列化,然后将序列化数据经过底层传输机制(IPC或者网络等)传递到目标进程内,然后在目标进程内进行反序列化,在内存中生成对象。
基于代理的对象调用方式
这种方式主要基于远程代理设计模式,适合长时间的面向连接的直接对象方法调用。基本思想是在Client端和Server端都增加一个代理(客户端称之为Stud,Server端称之为skeleton),调用请求由Stub封装并基于底层传输机制(IPC或者网络等)传送到skeleton,skeleton解封装后,调用Server的方法,然后再反方向返回。 这种方式,可以使得Client对于远程对象的范围,就如同本地对象一样。
IDL
IDL的伟大之处不是发明了一种新的描述语言,而是解决了异构系统间的远程通信,同时也给出了一个参考的模型(基于远程代理的模型)。一般的平台,当对于远程对象调用的方式基于代理模型实现时,一般都允许开发者为Server写一个IDL的描述,描述Server支持的接口服务,同时,平台会提供一个特殊的xidl工具,如微软的midl,高通的qidl,java的jidl,android的aidl等,主要的作用是,将通用的idl描述语言,翻译成特定的编程语言的接口定义(如C,Java,C++等),同时,自动生成相应的Stub,skeleton的参考代码,该代码的实现与具体的平台绑定,以利用特定的底层传输机制来实现远程访问。 比如,jidl生成的Stub,skeleton中,应该就是使用基于网络的远程对象访问。 而aidl生成的Stub,skeleton中,就是利用Android的IPC机制来完成Stub与skeleton间的通信。
BMP,android中的应用
BMP中的远程对象调用仅使用了基于Stub,skeleton的代理模型,并没有利用序列化对象的方式。 BMP提供QIDL工具,允许开发者为支持远程调用的Service组件写一个IDL的接口描述文件,然后利用QIDL自动生成特定于BMP平台的Stub,skeleton代码。 此后,Client使用远程对象时是完全透明的,完全和使用本地对象的方式一致。
Android中应该同时使用了序列化对象的方式和远程代理的方式。 Activity,Service间的Intent传递,应该就是使用的序列化对象方式进行远程对象传递。 而对于Service的远程调用,则使用了远程代理的方式,允许开发者为支持远程调用的Service组件写一个IDL的接口描述文件,然后利用AIDL自动生成特定于Android平台的Stub,skeleton代码(内部其实利用了IPC)。 此后,Client使用远程对象时是完全透明的,完全和使用本地对象的方式一致。