Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android跨進程通信-AIDL的使用

Android跨進程通信-AIDL的使用

編輯:關於Android編程

1、為什麼要有AIDL?

為什麼要有AIDL呢,官方文檔介紹AIDL中有這麼一句話:

Note: Using AIDL is necessary only ifyou allow clients from different applications to access your service forIPC and want to handle multithreading in your service. If you donot need to perform concurrent IPC across different applications, you should create yourinterfaceby implementing a Binder or, ifyou want to perform IPC, but donot need to handle multithreading, implement your interfaceusing a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.

第一句最重要,“只有當你允許來自不同的客戶端訪問你的服務並且需要處理多線程問題時你才必須使用AIDL”,其他情況下你都可以選擇其他方法,如使用Messager,也能跨進程通訊。可見AIDL是處理多線程、多客戶端並發訪問的。而Messager是單線程處理。還是官方文檔說的明白,一句話就可以理解為什麼要有AIDL。那麼是不是這樣的寫個AIDL試試。

2、AIDL的使用?

服務端:

服務端創建一個Service用來監聽客戶端的連接請求,然後創建一個AIDL文件,將暴露給客戶端的接口在這個AIDL文件中申明,最後在Service中實現這個AIDL接口即可。

客戶端:

首先需要綁定服務端的Service,綁定成功後,將服務端返回的Binder對象轉成AIDL接口所需要的類型,接著就可以調用AIDL中的方法了。

1.先建立一個android工程,用作服務端

創建一個android工程,用來充當跨進程通信的服務端。

2.創建一個包名用來存放aidl文件

創建一個包名用來存放aidl文件,比如com.ryg.sayhi.aidl,在裡面新建IMyService.aidl文件,如果需要訪問自定義對象,還需要建立對象的aidl文件,這裡我們由於使用了自定義對象Student,所以,還需要創建Student.aidl和Student.java。注意,這三個文件,需要都放在com.ryg.sayhi.aidl包裡。下面描述如何寫這三個文件。

IMyService.aidl代碼如下:

packagecom.ryg.sayhi.aidl;

importcom.ryg.sayhi.aidl.Student;

interfaceIMyService{

ListgetStudent();

voidaddStudent(inStudentstudent);

}

說明:

aidl中支持的參數類型為:基本類型(int,long,char,boolean等),String,CharSequence,List,Map,其他類型必須使用import導入,即使它們可能在同一個包裡,比如上面的Student,盡管它和IMyService在同一個包中,但是還是需要顯示的import進來。

另外,接口中的參數除了aidl支持的類型,其他類型必須標識其方向:到底是輸入還是輸出抑或兩者兼之,用in,out或者inout來表示,上面的代碼我們用in標記,因為它是輸入型參數。

在gen下面可以看到,eclipse為我們自動生成了一個代理類

public static abstract class Stub extends android.os.Binder implements com.ryg.sayhi.aidl.IMyService

可見這個Stub類就是一個普通的Binder,只不過它實現了我們定義的aidl接口。它還有一個靜態方法

public static com.ryg.sayhi.aidl.IMyService asInterface(android.os.IBinder obj)

這個方法很有用,通過它,我們就可以在客戶端中得到IMyService的實例,進而通過實例來調用其方法。

Student.aidl代碼如下:

packagecom.ryg.sayhi.aidl;

parcelableStudent;

說明:這裡parcelable是個類型,首字母是小寫的,和Parcelable接口不是一個東西,要注意。

Student.java代碼如下:

packagecom.ryg.sayhi.aidl;

importjava.util.Locale;

importandroid.os.Parcel;

importandroid.os.Parcelable;

publicfinalclassStudentimplementsParcelable{

publicstaticfinalintSEX_MALE=1;

publicstaticfinalintSEX_FEMALE=2;

publicintsno;

publicStringname;

publicintsex;

publicintage;

publicStudent(){

}

publicstaticfinalParcelable.CreatorCREATOR=new

Parcelable.Creator(){

publicStudentcreateFromParcel(Parcelin){

returnnewStudent(in);

}

publicStudent[]newArray(intsize){

returnnewStudent[size];

}

};

privateStudent(Parcelin){

readFromParcel(in);

}

@Override

publicintdescribeContents(){

return0;

}

@Override

publicvoidwriteToParcel(Parceldest,intflags){

dest.writeInt(sno);

dest.writeString(name);

dest.writeInt(sex);

dest.writeInt(age);

}

publicvoidreadFromParcel(Parcelin){

sno=in.readInt();

name=in.readString();

sex=in.readInt();

age=in.readInt();

}

@Override

publicStringtoString(){

returnString.format(Locale.ENGLISH,"Student[%d,%s,%d,%d]",sno,name,sex,age);

}

} 說明:通過AIDL傳輸非基本類型的對象,被傳輸的對象需要序列化,序列化功能java有提供,但是android sdk提供了更輕量級更方便的方法,即實現Parcelable接口,關於android的序列化。這裡只要簡單理解一下就行,大意是要實現如下函數

readFromParcel : 從parcel中讀取對象

writeToParcel :將對象寫入parcel

describeContents:返回0即可

Parcelable.Creator CREATOR:這個照著上面的代碼抄就可以

需要注意的是,readFromParcel和writeToParcel操作數據成員的順序要一致錨點

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved