如何使用AIDL

如何使用AIDL

AIDL(Android介面定義語言):
當行程想開放功能性給其他行程時, 可透過AIDL來進行定義,
編譯後會產生支援行程間溝通(IPC, Interprocess communication)的java檔案。

利用IDE可以快速地產生.aidl的檔案, AIDL會自動幫你處理包覆Binder等一些細節,
讓你在操作上就跟使用interface一樣簡單。

  • 同步RPC(Remote Procedure Call)

如果你在aidl內定義, 那麼就可以透過這個方法來給client端呼叫, 並且回傳一個字串給client端。

interface IMyAidlInterface {    
    String getThreadName();
}

server端, 在Service當中, 實作了AIDL所產生的interface, 並且實作成Binder,
透過Binder可以呼叫我們所提供的方法, 並回傳一個字串。

private IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub(){    
    @Override    
    public String getThreadName() throws RemoteException {      
        return MyActivity.class.getName();    
    }
};

AIDL Client端, 實作同樣的AIDL, 只是他必須拿到Server端的Binder以後才能取得字串。

try {    
    IMyAidlInterface mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(binder);    
    String threadName = mIMyAidlInterface.getThreadName();
} catch (RemoteException e) {    
    e.printStackTrace();
}

由於這樣是進行同步, Binder Thread Pool是有限的,
當多個Client端呼叫Server端, 導致其他的Thread會進入等待。

優點: 單純、好實做、執行緒安全
缺點: 用戶端會被Blocking
  • 非同步RPC:
    如果要實做非同步, 方法宣告為oneway且回傳值就都是void, 取而代之的是Callback。
    當實作非同步的話, 只要RPC交易成功,
    Binder會把Callback丟給Server端, 等到執行完畢後,
    再由Server端去呼叫Callback。

Server端定義AIDL, 如果你要使用非同步就要將方法設定為oneway,
如果你定義在interface, 則代表所有的方法都是非同步。

import personal.givemepass.myapplication.IMyAidlInterfaceCallback;
interface IMyAidlInterface {    
    oneway void getThreadName(IMyAidlInterfaceCallback callback);
}

實做Server端, 跟前面同步相同,

private final IMyAidlInterface.Stub server = new IMyAidlInterface.Stub(){    
    @Override public void getThreadName(IMyAidlInterfaceCallback callback) 
        throws RemoteException {        
        String name = "aaa";            
        callback.handleMessage(name);      
    }
};

實作Client端

private IMyAidlInterfaceCallback.Stub mClient = 
    new IMyAidlInterfaceCallback.Stub(){           
        @Override 
        public void handleMessage(String name) throws RemoteException {       
            //client 接收        
        }
};

這樣就完成非同步的AIDL了。