1. 程式人生 > >AIDL檔案中使用實現介面Parcelable的類

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是兩者均可設定。
    AIDL只支援介面方法,不能公開static變數。 其中就說明了可以使用:Parcelable介面的類

比如:IMyService.aidl

package com.demo; 

import com.demo.Person; 

interface IMyService { 
void savePersonInfo(in Person person); 
        List<Person> getAllPerson(); 
}

在這裡使用了Person類,如果Person沒有使用什麼神奇的功效是不可使用在這裡的。

看下:Person類的神奇之地:

publicclass

 Person implements Parcelable { 

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的使用在這裡簡單的描述下:

是一個序列化的類,這裡使用Parcelable 介面來序列化,是Android提供的一個比Serializable 效率更高的序列化類。     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",沒有“:”分號的,則建立全域性程序,不同的應用程式共享該程序。不加,可能會提示空指標異常。