最近做跨進(jìn)程下載時(shí)遇到一個(gè)問題差點(diǎn)引起血案窖贤,所以在此記錄一下。
問題是這樣的:客戶端調(diào)用下載庫下載視頻滤蝠,下載庫是在一個(gè)獨(dú)立的進(jìn)程里運(yùn)行授嘀。下載庫需要通過Binder回調(diào)客戶端獲取下載地址,然后下載庫獲取到下載地址進(jìn)行視頻下載粤攒。遇到的問題是下載庫通過Binder回調(diào)客戶端獲取到的下載地址為null夯接。
此問題涉及到兩個(gè)進(jìn)程里的三個(gè)線程,兩個(gè)進(jìn)程分別是客戶端進(jìn)程和下載庫獨(dú)立進(jìn)程盔几。三個(gè)線程分別是客戶端獲取視頻列表的子線程ThreadA、下載庫里的任務(wù)下載線程ThreadB以及在ThreadB中通過Binder調(diào)用客戶端的回調(diào)方法上鞠,因?yàn)橥ㄟ^Binder調(diào)用的方法不會(huì)在ThreadB中而是在BinderC線程中。因?yàn)槭窃赥hreadB中調(diào)用BinderC線程芍阎,這就涉及到線程同步問題。所以就以為是線程不同步造成煩人獲取不到下載地址問題轮听。解決了ThreadB與BinderC的同步問題岭佳,發(fā)現(xiàn)通過Binder還是回調(diào)得不到下載地址。排除線程同步問題珊随。
因?yàn)椴皇撬械囊曨l下載都獲取不到下載地址,所以就想是不是AIDL傳輸時(shí)數(shù)據(jù)格式的問題鲫凶。 查了下資料AIDL支持的數(shù)據(jù)格式有:
基本數(shù)據(jù)類型(int京办,long,char惭婿,boolean财饥,double等)
String和CharSequence
List:只支持ArrayList,而且list中的元素也必須是AIDL支持的類型
Map:只支持HashMap钥星,里面的key和value也必須是AIDL支持的類型
Parceable:所有實(shí)現(xiàn)了Parceable接口的對(duì)象
看到這里恍然大悟满着,與下載庫進(jìn)程通信的數(shù)據(jù)對(duì)象里包含一個(gè)枚舉類型,而通過Parceable序列化對(duì)象時(shí)是自動(dòng)過濾掉枚舉類型的宁改。下載庫通過AIDL的方式獲取客戶端的下載地址的方法里正好是通過這個(gè)枚舉類型判斷的魂莫,因?yàn)镻arceable序列化時(shí)過濾了枚舉類型的字段,所以得到的結(jié)果為null。
造成獲取不到下載地址的根本原因是AIDL通信時(shí)包含枚舉類型是該怎么處理潭兽。
下面給出包含枚舉類型字段的Parceable對(duì)象的正確實(shí)現(xiàn)
public class DownLoadInfo implements Parcelable {
public int id;
public String download_url;
public DoWnLoadType doWnLoadType;
protected DownLoadInfo(Parcel in) {
id = in.readInt();
download_url = in.readString();
//使用該方式來讀取枚舉的值斗遏。。怒坯。Parcelable默認(rèn)不實(shí)現(xiàn)
doWnLoadType = DoWnLoadType.values()[in.readInt()];
}
public static final Creator<DownLoadInfo> CREATOR = new Creator<DownLoadInfo>() {
@Override
public DownLoadInfo createFromParcel(Parcel in) {
return new DownLoadInfo(in);
}
@Override
public DownLoadInfo[] newArray(int size) {
return new DownLoadInfo[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(download_url);
//使用該方式來寫入枚舉藻懒。。嬉荆。Parcelable默認(rèn)不實(shí)現(xiàn) parcel.writeInt(doWnLoadType.ordinal());
}
public enum DoWnLoadType {
Shark, Koo;
}
}