AIDL檔案中使用實現介面Parcelable的類
在官方文件中說明了,在AIDL檔案中可以使用:
AIDL使用簡單的語法來宣告介面,描述其方法以及方法的引數和返回值。這些引數和返回值可以是任何型別,甚至是其他AIDL生成的介面。 其中對於Java程式語言的基本資料型別 (int, long, char, boolean等),String和CharSequence,集合介面型別List和Map,不需要import 語句。 而如果需要在AIDL中使用其他AIDL介面型別,需要import,即使是在相同包結構下。AIDL允許傳遞實現Parcelable介面的類,需要import.需要特別注意的是,對於非基本資料型別,也不是String和CharSequence型別的,需要有方向指示,包括in、out和inout,in表示由客戶端設定,out表示由服務端設定,inout是兩者均可設定。
比如:IMyService.aidl
package com.demo;
import com.demo.Person;
interface IMyService {
void savePersonInfo(in
Person person);
List<Person> getAllPerson();
}
在這裡使用了Person類,如果Person沒有使用什麼神奇的功效是不可使用在這裡的。
看下:Person類的神奇之地:
publicclass
private String
name;
private String
telNumber;
privateint age;
public Person()
{}
public Person(Parcel pl){
name = pl.readString();
telNumber = pl.readString();
age = pl.readInt();
}
public String
getName() {
return name;
}
publicvoid setName(String
name) {
this.name
= name;
}
public String
getTelNumber() {
return telNumber;
}
publicvoid setTelNumber(String
telNumber) {
this.telNumber
= telNumber;
}
publicint getAge()
{
return age;
}
publicvoid setAge(int age)
{
this.age
= age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(telNumber);
dest.writeInt(age);
}
public static final Parcelable.Creator<Person>
CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person
createFromParcel(Parcel source) {
return new Person(source);
}
@Override
public Person[]
newArray(int size) {
return new Person[size];
}
};
}
對於Parcelable的使用在這裡簡單的描述下:
1) void writeToParcel(Parcel dest, int flags) 將需要序列化儲存的資料寫入外部提供的Parcel物件dest。而看了網上的程式碼例子,個人猜測,讀取Parcel資料的次序要和這裡的write次序一致,否則可能會讀錯資料。具體情況我沒試驗過!
2) describeContents() 沒搞懂有什麼用,反正直接返回0也可以
3) static final Parcelable.Creator物件CREATOR 這個CREATOR命名是固定的,而它對應的介面有兩個方法:
createFromParcel(Parcel source) 實現從source創建出JavaBean例項的功能。 最後,別忘了建立檔案 Person.aidl 內容如下: package com.demo;
parcelable Person;
注意這裡的parcelable和原來實現的Parcelable 介面,開頭的字母p一個小寫一個大寫。
對於實現AIDL介面,官方還提醒我們: 1. 呼叫者是不能保證在主執行緒執行的,所以從一呼叫的開始就需要考慮多執行緒處理,以及確保執行緒安全; 2. IPC呼叫是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主執行緒中呼叫。也就是IPC呼叫會掛起應用程式導致介面失去響應,這種情況應該考慮單獨開啟一個執行緒來處理。
3. 丟擲的異常是不能返回給呼叫者(跨程序拋異常處理是不可取的)。
對於,其他的部分見前面的一文:Android 服務Service <serviceandroid:name=".YourService"android:process=":remote">
<intent-filter>
<actionandroid:name="com.demo.IMyService"/>
</intent-filter>
</service>
android:process=":remote",代表在應用程式裡,當需要該service時,會自動建立新的程序。而如果是android:process="remote",沒有“:”分號的,則建立全域性程序,不同的應用程式共享該程序。不加,可能會提示空指標異常。