本節中我們只需要關注Java Framework中StorageManager和MountService。
在開始本章之前,先向大家介紹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文件,如下所示(刪除部分內容,方便舉例)
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/storage/IMountService.aidl
*/
package android.os.storage;
/** WARNING! Update IMountService.h and IMountService.cpp if you change this file.
* In particular, the ordering of the methods below must match the
* _TRANSACTION enum in IMountService.cpp
* @hide - Applications should use android.os.storage.StorageManager to access
* storage functions.
*/
public interface IMountService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.storage.IMountService
{
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
。。。。。。。。。。。
case TRANSACTION_registerListener:
{
data.enforceInterface(DESCRIPTOR);
android.os.storage.IMountServiceListener _arg0;
_arg0 = android.os.storage.IMountServiceListener.Stub.asInterface(data.readStrongBinder());
this.registerListener(_arg0);
reply.writeNoException();
return true;
}
。。。。。。。。。。。
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.storage.IMountService
{
。。。。。。。。。。。。。。。。
/**
* Registers an IMountServiceListener for receiving async
* notifications.
*/
public void registerListener(android.os.storage.IMountServiceListener listener) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((listener!=null))?(listener.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
。。。。。。。。。。。。。。。。
}
可以看到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返回
² 客戶端取回數據