Android AIDL——實現機制淺析

來源:互聯網
上載者:User

1.基於前面寫的aidl使用,這段時間準備研究ActivityManager架構,對aidl進行了更深入的研究,因為android架構大量使用了 進程通訊機制,所以,在研究android framework前認真研究一下AIDL的實現機制十分有必要的

  2.前面講了aidl是 Android Interface definition language的縮寫,它是一種進程通訊介面的描述,通過sdk解譯器對器進行編譯,會把它編譯成java代碼在gen目錄下,類路徑與aidl檔案的 類路徑相同。

  3.aidl介面
package com.cao.android.demos.binder.aidl;  
import com.cao.android.demos.binder.aidl.AIDLActivity;
interface AIDLService {   
    void registerTestCall(AIDLActivity cb);   
    void invokCallBack();
}

 

AIDLService.java詳細描述了aidl介面的實現,看上面圖示,AIDLActivity.aidl編譯成了一個介面 AIDLActivity,一個存根類Stub,一個代理類Proxy
public interface AIDLService extends android.os.IInterface//與AIDLActivity.aidl中定義的介面對應的java介面實現
public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService
//繼承android.os.Binder,在onTransact完成對通訊資料的接收,通過不同通訊參數code調用AIDLService介面方 法,並回寫調用返回結果AIDLService介面方法需要在
//服務端實現
private static class Proxy implements com.cao.android.demos.binder.aidl.AIDLService
//實現AIDLService介面方法,但是方法只是執行代理遠程叫用作業,具體方法操作在遠端的Stub存根類中實現

 

總的來說,AIDLActivity.aidl編譯會產生一個AIDLActivity介面,一個stub存根抽像類,一個proxy代理類,這個 實現其實根axis的wsdl檔案編譯產生思路是一致的,
stub存根抽像類需要在服務端實現,proxy代理類被用戶端使用,通過stub,proxy的封裝,屏蔽了進程通訊的細節,對使用者來說就只是一個 AIDLActivity介面的調用

 

  4.根據以上思路使用aidl再看一下AIDLService調用實現代碼
--1.在服務端實現AIDLService.Stub抽象類別,在服務端onBind方法中返回該實作類別
--2.用戶端綁定service時在ServiceConnection.onServiceConnected擷取onBind返回的IBinder 對象
        private ServiceConnection mConnection = new ServiceConnection() {
                public void onServiceConnected(ComponentName className, IBinder service) {
                        Log("connect service");
                        mService = AIDLService.Stub.asInterface(service);
                        try {
                                mService.registerTestCall(mCallback);
                        } catch (RemoteException e) {

                        }
                }
        注意mConnection在bindservice作為調用參數:bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
--3.AIDLService.Stub.asInterface(service);
public static com.cao.android.demos.binder.aidl.AIDLService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
//如果bindService綁定的是同一進程的service,返回的是服務端Stub對象本省,那麼在用戶端是直接操作Stub對象,並不進行進程 通訊了
if (((iin!=null)&&(iin instanceof com.cao.android.demos.binder.aidl.AIDLService))) {
return ((com.cao.android.demos.binder.aidl.AIDLService)iin);
}
//bindService綁定的不是同一進程的service,返回的是代理對象,obj==android.os.BinderProxy對象,被包 裝成一個AIDLService.Stub.Proxy代理對象
//不過AIDLService.Stub.Proxy處理序間通訊通過android.os.BinderProxy實現
return new com.cao.android.demos.binder.aidl.AIDLService.Stub.Proxy(obj);
}
--4.調用AIDLService介面方法,如果是同一進程,AIDLService就是service的Stub對象,等同直接調用Stub對象實現 的AIDLService介面方法
如果是一個proxy對象,那就是在進程間調用了,我們看一個用戶端調用的例子:
                        public void onClick(View v) {
                                Log("AIDLTestActivity.btnCallBack");
                                try {
                                        mService.invokCallBack();
                                } catch (RemoteException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
        --mService.invokCallBack()等同調用Proxy.invokCallBack,這個時候是進程間調用,我們看代理方法的實現
public void invokCallBack() throws android.os.RemoteException
{
//構造一個Parcel對象,該對象可在進程間傳輸
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
//DESCRIPTOR = "com.cao.android.demos.binder.aidl.AIDLService",描述了調用哪個Stub對象
_data.writeInterfaceToken(DESCRIPTOR);
//Stub.TRANSACTION_invokCallBack標識調用Stub中哪個介面方法,mRemote在是構造Proxy對象的參數 obj,也就是public void onServiceConnected(ComponentName className, IBinder service)
//中的service參數,它是一個BinderProxy對象,負責傳輸進程間資料。
mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
--5.BinderProxy.transact 該方法本地化實現
   public native boolean transact(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;
        //對應實現的本地化代碼 /frameworks/base/core/jni/android_util_Binder.cpp->static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
                                                jint code, jobject dataObj,
                                                jobject replyObj, jint flags)
  //具體進程通訊在c代碼中如何?,以後再深入研究。
--6.服務端進程資料接收
        --呼叫堆疊
        ##AIDLService.Stub.onTransact
        ##AIDLService.Stub(Binder).execTransact
        ##NativeStart.run
        --AIDLService.Stub.onTransact
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_registerTestCall:
{
data.enforceInterface(DESCRIPTOR);
com.cao.android.demos.binder.aidl.AIDLActivity _arg0;
_arg0 = com.cao.android.demos.binder.aidl.AIDLActivity.Stub.asInterface(data.readStrongBinder());
this.registerTestCall(_arg0);
reply.writeNoException();
return true;
}
//TRANSACTION_invokCallBack由前面用戶端調用的時候transact方法參數決 定,code==TRANSACTION_invokCallBack,執行
//invokCallBack方法,方法由繼承Stud的服務端存根類實現。
case TRANSACTION_invokCallBack:
{
data.enforceInterface(DESCRIPTOR);
this.invokCallBack();
reply.writeNoException();
return true;
}

5.裡面設定本地C代碼的調用,我沒有深入研究,隨著後面我對android架構的深入,我會發blog進一步說民底層C代碼是如何?進程通訊 的,關於AIDL進程通訊,暫時研究到這裡。

 

原文: http://my.oschina.net/u/213924/blog/37310

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.