AIDL = Android Interface Definition Language
進程之間如何通訊呢?在Windows系統中存在IPC管道服務、消息等方法。在Java中,由於不允許跨進程記憶體共用,因此傳遞物件,只能把物件拆分成作業系統能理解的簡單形式,以達到跨界物件訪問的目的。因此J2EE採用RMI的方式,可以通過序列化傳遞物件。
而Android則採用所謂的AIDL接口定義語言。AIDL能夠建立一個interface(aidl檔),編譯器可根據aidl檔生成一段代碼,通過預先定義的介面讓不同process之間進行資訊的傳遞(e.g. IPC)。Client Process可以藉由Bind Service Process來取得資訊。
如何使用AIDL? (以Eclipse開發為例)
AIDL的跨進程(IPC)的遠距溝通機制和COM或CORBA類似,是基於介面的。它使用代理類在用戶端和實現層間傳遞值。步驟如下:
1. 創建aidl文件。這個文件定義了一個接口(XXX.aidl),該介面定義了可供用戶端訪問的方法和屬性。
NOTE:理論上,參數可以傳遞基底資料型別和String,還有Bundle的派生類。不過在Eclipse中,目前的ADT不支援Bundle做為參數。[來源:AIDL --- Android中的遠程接口, 2010.7]
ex: src/IHelloServiceBinder.aidl
package [your package name]
interface IHelloServiceBinder {
String getServiceName();
}
2. 在Java檔中實現你的接口方法。編譯器會根據AIDL介面, 產生一個Java介面,這這個介面有一個名為Stub的內部抽象類別,它繼承擴展了介面並實現了遠端調用需要的幾個方法。
經過"Build Project"之後,gen/目錄下會自動產生對應的 .java檔,此interface檔案中包含了一個名為Stub的subclass (a binder)。 ex: IHelloServiceBinder.java
3. 暴露你的接口給客戶端。AIDL介面的實現,在Service中以內嵌類的方式實作interface,並且在onBind()回傳該interface。
public class HelloService extends Service {
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IHelloServiceBinder.Stub mBinder
= new IHelloServiceBinder.Stub() {
// Implement AIDL Interface
@Override
public String getServiceName()
throws RemoteException {
throws RemoteException {
return "HelloService";
}
};
}
AndroidManifest.xml
<application
...
<service
android:name=".HelloService"
android:process=":remote" />
...
</application>
4. 在Client端進行遠端調用。Client process在bind service之後 (待service回傳IBinder之後) 即可對service提供的method進行操作。
NOTE: aidl檔在client和service的src/目錄下都要存在一份(複製過去即可),雙方才知道此interface [來源:Android AIDL的使用, 2012.12]
public class MainActivity extends Activity {
IHelloServiceBinder mIHelloServiceBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Bind Service
Intent intent
= new Intent(this, HelloService.class);
= new Intent(this, HelloService.class);
bindService(intent,
mConnection, Context.BIND_AUTO_CREATE);
mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection
= new ServiceConnection() {
= new ServiceConnection() {
public void onServiceConnected(ComponentName
className, IBinder service) {
className, IBinder service) {
// Get an instance of IHelloServiceBinder
mIHelloServiceBinder = IHelloServiceBinder.
Stub.asInterface(service);
Stub.asInterface(service);
try {
Log.d("AIDL Test", mIHelloServiceBinder.
getServiceName());
getServiceName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
// Called when the connection
// with the service disconnects unexpectedly
// with the service disconnects unexpectedly
public void onServiceDisconnected(
ComponentName className) {
ComponentName className) {
mIHelloServiceBinder = null;
}
};
}
留言
張貼留言