2012年12月27日 星期四

Android AIDL的使用

AIDL(Android Interface Definition Language)能夠讓建立一個interface, 讓不同的process之間進行資訊的傳遞(e.g. IPC)
client process可以藉由bind service process來取得資訊, 步驟如下 : 


1. 在專案中的src/目錄下建立aidl檔, ex: IRemoteService.aidl
package com.example.android;
/* Example service interface */
interface IRemoteService
{
   // Request the process ID of this service
   int getPid();
}
經過build之後就會在gen/目錄下產生對應的.java檔, ex: IRemoteService.java 


2. 在service端實作該interface
在剛剛產生的.java interface檔案中包含了一個名為Stub的subclass(a binder)
實作該interface, 並且在service的onBind()回傳該interface
public class RemoteService extends Service
{
   @Override
   public IBinder onBind(Intent intent)
   {
       // Return the interface
       return mBinder;
   }
   private final IRemoteService.Stub mBinder = new IRemoteService.Stub()
   {
       // Implement the interface
       public int getPid()
       {
           return Process.myPid();
       }
   };
}


3. client process可以藉由bind service與service進行溝通
client process在bind service之後(待service回傳IBinder之後)即可對service提供的method進行操作
IRemoteService mIRemoteService;
private ServiceConnection mConnection = new ServiceConnection() 
{
   // Called when the connection with the service is established
   public void onServiceConnected(ComponentName className, IBinder service) 
   {
       // This gets an instance of the IRemoteInterface, which we can use to call on the service
       mIRemoteService = IRemoteService.Stub.asInterface(service);
       // Call method of service
       mIRemoteService.getPid();
       
   }
   // Called when the connection with the service disconnects unexpectedly
   public void onServiceDisconnected(ComponentName className) 
   {
       mIRemoteService = null;
   }
};


注意事項 : aidl檔在client和service的src/目錄下都要存在一份(複製過去即可), 雙方才知道此interface