android使用aidl實現進程間通訊

Android每一個應用程序都有本身的進程,當須要在不一樣的進程之間傳遞對象時,該如何實現呢?java

顯然,Java中是不支持跨進程內存共享的。所以要傳遞對象須要把對象解析成操做系統可以理解的數據格式以達到跨界對象訪問的目的。JavaEE中,採用RMI經過序列化傳遞對象。android

AndroidAIDL(Android Interface Definition Language:接口定義語言)方式實現。eclipse


AIDL是一種接口定義語言,用於約束兩個進程間的通信規則,供編譯器生成代碼,實現Android設備上的兩個進程間通訊(IPC)因爲進程之間的通訊信息須要雙向轉換,因此android採用代理類在背後實現了信息的雙向轉換,代理類由android編譯器生成,對開發人員來講是透明的。ide


具體實現this

假設A應用須要與B應用進行通訊,調用B應用中的download(String path)方法,B應用以Service方式向A應用提供服務。須要下面四個步驟spa

1 在B應用中建立*.aidl文件aidl文件的定義和接口的定義很相類,如:在com.alex.aidl包下建立IDownloadService.aidl文件,內容以下:操作系統

package com.alex.aidl;
interface IDownloadService {
void download(String path);
}

當完成aidl文件建立後,eclipse會自動在項目的gen目錄中同步生成IDownloadService.java接口文件。接口文件中生成一個Stub的抽象類,裏面包括aidl定義的方法,還包括一些其它輔助方法。值得關注的是asInterface(IBinder iBinder),它返回接口類型的實例,對於遠程服務調用,遠程服務返回給客戶端的對象爲代理對象,客戶端在onServiceConnected(ComponentName name, IBinder service)方法引用該對象時不能直接強轉成接口類型的實例,而應該使用asInterface(IBinder iBinder)進行類型轉換。代理


2B應用中實現aidl文件生成的接口(本例是IDownloadService),但並不是直接實現接口,而是經過繼承接口的Stub來實現(Stub抽象類內部實現了aidl接口),而且實現接口方法的代碼。內容以下:code

public class ServiceBinder extends IDownloadService.Stub {
@Override
public void download(String path) throws RemoteException {
Log.i("DownloadService", path);
}
}

3 在B應用中建立一個Service(服務),在服務的onBind(Intent intent)方法中返回實現了aidl接口的對象(本例是ServiceBinder)。內容以下:xml

public class DownloadService extends Service {
private ServiceBinder serviceBinder = new ServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return serviceBinder;
}
public class ServiceBinder extends IDownloadService.Stub {
@Override
public void download(String path) throws RemoteException {
Log.i("DownloadService", path);
}
}
}


其餘應用能夠經過隱式意圖訪問服務,意圖的動做能夠自定義,AndroidManifest.xml配置代碼以下:

<service android:name=".DownloadService" >
<intent-filter>
<action android:name="com.alex.process.aidl.DownloadService" />
</intent-filter>
</service>


4 把B應用中aidl文件所在package連同aidl文件一塊兒拷貝到客戶端A應用eclipse會自動在A應用的gen目錄中爲aidl文件同步生成IDownloadService.java接口文件,接下來就能夠在A應用中實現與B應用通訊,代碼以下:

public class ClientActivity extends Activity {
private IDownloadService downloadService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.bindService(new Intent("com.alex.process.aidl.DownloadService"), 
                                    this.serviceConnection, BIND_AUTO_CREATE);//綁定到服務
}
@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(serviceConnection);//解除服務
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
downloadService = IDownloadService.Stub.asInterface(service);
try {
downloadService.download("http://www.test.com/...");
} catch (RemoteException e) {
Log.e("ClientActivity", e.toString());
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
downloadService = null;
}
};
}
相關文章
相關標籤/搜索