Android AIDL——實現機制淺析

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

  2.前面講了aidl是 Android Interface definitionlanguage的縮寫,它是一種進程通信接口的描述,通過sdk解釋器對器進行編譯,會把它編譯成java代碼在gen目錄下,類路徑與aidl文件的類路徑相同。

  3.aidl接口
packagecom.cao.android.demos.binder.aidl;  
import com.cao.android.demos.binder.aidl.AIDLActivity;
interface AIDLService{   
    voidregisterTestCall(AIDLActivitycb);   
    voidinvokCallBack();
}

它編譯後生成的java文件如下

AIDLService.java詳細描述了aidl接口的實現,看上面圖示,AIDLActivity.aidl編譯成了一個接口AIDLActivity,一個存根類Stub,一個代理類Proxy
public interface AIDLService extendsandroid.os.IInterface//與AIDLActivity.aidl中定義的接口對應的java接口實現
public static abstract class Stub extends android.os.Binderimplements com.cao.android.demos.binder.aidl.AIDLService
//繼承android.os.Binder,在onTransact完成對通信數據的接收,通過不同通信參數code調用AIDLService接口方法,並回寫調用返回結果AIDLService接口方法需要在
//服務端實現
private static class Proxy implementscom.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, IBinderservice) {
                       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.AIDLServiceasInterface(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 instanceofcom.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 newcom.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
              

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章