转自:android usb流程(转载加整理)
在StorageManager的构造函数中,用到了IMountService,我们这里就讲一下它。
public StorageManager(Looper tgtLooper) throws RemoteException { mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); if (mMountService == null) { Log.e(TAG, "Unable to connect to mount service! - is it running yet?"); return; } mTgtLooper = tgtLooper; mBinderListener = new MountServiceBinderListener(); mMountService.registerListener(mBinderListener); }这里需要讲到一个概念,AIDL
AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,使在一个Android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
AIDL IPC的机制是基于接口的,和COM或Corba类似,但它是轻量级的。它使用代理类在客户端和实现层间传递值。
先向大家介绍COM的一个概念---------Proxy/Stub结构(代理/存根结构)
打个比方,你到自动取款机上去取款;你就是客户,取款机就是你的代理;你不会在乎钱具体放在那里,你只想看到足够或更多的钱从出口出来(这就是com的透明性)。你同银行之间的操作完全是取款机代理实现。你的取款请求通过取款机,传到另一头,银行的服务器,他也没有必要知道你在哪儿取钱,他所关心的是你的身份,和你取款多少。当他确认你的权限,就进行相应的操作,返回操作结果给取款机,取款机根据服务器返回结果,从保险柜里取出相应数量的钱给你。你取出卡后,操作完成。取款机不是直接同服务器连接的,他们之间还有一个“存根”,取款机与存根通信,服务器与存根通信。从某种意义上说存根就是服务器的代理。(参考COM代理与存根)
AIDLFramework层的架构,如下图:
换而言之,Android就是在传统的C/S架构中加入了一层,实现IPC。图中表明,AIDL类似COM的Proxy/Stub架构。不过是现在android自己的序列化类Pacel。
以USB Mass Storage架构举例。看看到底什么是AIDL的framework层的实现。编写好aidl文件,运用aidl工具生成IMountService.java文件,如下所示
public interface IMountService extends IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends Binder implements IMountService { private static class Proxy implements IMountService { private final IBinder mRemote; Proxy(IBinder remote) { mRemote = remote; } public IBinder asBinder() { return mRemote; } public String getInterfaceDescriptor() { return DESCRIPTOR; }
可以看到IMountService 中的Stub继承Binder和IMountService
看过源代码,我们不难发现上图中对应的角色:
Client ------ StorageManager
Proxy ------ IMountServie.Stub.Proxy
Parcel ------对象序列化类,数据只有继承Parcelable才能进行RPC
Stub ------ IMountService.Stub
Server ------ MountService
当StorageManager调用MountService方法时,例如调用registerListener,步骤如下:
? 进入IMountServie.Stub.Proxy找到对应的方法registerListener。
? IMountServie.Stub.ProxyregisterListener利用Parcel将函数调用的序列化为android理解的结构
? 调用onTransact函数,onTransact根据参数,找到对应registerListener Switch-case语句执行
? 数据通过Binder机制进行写操作,客户端调用阻塞,等待服务端reply
? 服务端处理完request返回
? 客户端取回数据
相关文章:
Android 框架层为IMountService 增加新接口