談及android跨進程數據傳遞,腦袋中不乏浮現出ContentProvider、AIDL、 Messenger、Intent等,對,的確這些都可以實現,但今天我們不談這些,僅注重於數據。跨進程傳遞數據,常需要序列化操作,也許初次接觸序列化這個名詞,可能大家會覺得很抽象,其實,可以把其想象成一個吹氣球的過程,序列化就是把一個吹好的氣球放掉氣,反序列化就是把一個放了氣的氣球重新吹起來,這樣一說,是不是好懂很多。
目前android支持有兩個接口可實現序列化操作(Serializable 和 Parcelable),只要我們實現了它們其中一個,就可以輕鬆地實現數據的傳遞,對常用的數據類型即AIDL傳遞支持的類型,通過Android Studio就可以自動生成(CharSequence例外),也不需要我們去實現序列化接口,因此對其也不需贅述。先重點關注AIDL傳遞自定義對象,對此,一般需要我們主動去實現Parcelable,只要自定義的對象沒有包含複雜的屬性,一般操作起來還是十分快捷。一般步驟是:
Step1:判斷成員屬性是不是AIDL傳遞支持的類型,不是則跳Step2,否則跳轉Step3;
Step2:判斷成員屬性是不是實現了Parcelable接口,不是則跳轉Step1,否則跳Step3;
Step3:撰寫Write和read方法,分別對應氣球放氣和吹氣的過程;
注意:對屬性進行write和read操作一定要順序一致,否則就會報錯
好了,有了這個步驟,寫起來代碼來也就底氣十分,按圖索驥即可。最近我碰到個問題,如何傳遞SparseArrayCompat<E>和嵌套的集合類(如:List< List<E> >),初次面對這個問題,一般在想AIDL不支持這些類型呀,儘管E實現了Parcelable,但是SparseArrayCompat<E>作爲一個整體還是不支持呀,怎麼辦呢?瞬間進入死衚衕不能自拔!
N久之後,靈光一閃,序列化不就是放棄和吹氣的過程嗎,貌似沒有強制說SparseArrayCompat<E>就一定要以SparseArrayCompat<E>類型傳遞吧,只要我能放掉氣,又能吹起來不就可以了嗎?以String類型爲例,下面代碼就產生了:
read代碼:
public SparseArrayCompat<String> readSparseArrayCompat(Parcel in){
SparseArrayCompat<String> data = new SparseArrayCompat<>();
int size = in.readInt();
for(int i = 0;i<size;++i){
Integer key = in.readInt();
String value = in.readString();
data.put(key,value);
}
return data;
}
write代碼:
public void writeSparseArrayCompat(Parcel dest,SparseArrayCompat<String> data) {
if (data == null || data.size() <= 0) return;
int size = data.size();
dest.writeInt(size);
for (int i = 0; i < size; ++i) {
dest.writeInt(data.keyAt(i));
dest.writeString(data.valueAt(i));
}
}
說了這麼多,其實也就是想說明這麼一點:換種思路海闊天空