AIDL原理之Framewok層實現

本節中我們只需要關注Java FrameworkStorageManagerMountService

在開始本章之前,先向大家介紹COM的一個概念---------Proxy/Stub結構(代理/存根結構)


 

打個比方,你到自動取款機上去取款;你就是客戶,取款機就是你的代理;你不會在乎錢具體放在那裏,你只想看到足夠或更多的錢從出口出來(這就是com的透明性)。你同銀行之間的操作完全是取款機代理實現。你的取款請求通過取款機,傳到另一頭,銀行的服務器,他也沒有必要知道你在哪兒取錢,他所關心的是你的身份,和你取款多少。當他確認你的權限,就進行相應的操作,返回操作結果給取款機,取款機根據服務器返回結果,從保險櫃裏取出相應數量的錢給你。你取出卡後,操作完成。取款機不是直接同服務器連接的,他們之間還有一個存根,取款機與存根通信,服務器與存根通信。從某種意義上說存根就是服務器的代理。(參考COM代理與存根

AIDLFramework層的架構,如下圖:


換而言之,Android就是在傳統的C/S架構中加入了一層,實現IPC。圖中表明,AIDL類似COMProxy/Stub架構。不過是現在android自己的序列化類Pacel

USB Mass Storage架構舉例。看看到底什麼是AIDLframework層的實現。編寫好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繼承BinderIMountService

看過源代碼,我們不難發現上圖中對應的角色:

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返回

² 客戶端取回數據

發佈了21 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章