????????我們知道在Activity間使用Intent傳遞List含有大量序列化的對(duì)象的時(shí)候,或者傳遞較大bitmap等較大量數(shù)據(jù)的時(shí)候會(huì)引起頁面卡頓。而且Android本身也限制了能夠傳遞的數(shù)據(jù)大小在1MB左右。這就要求我們不得不為傳輸大量數(shù)據(jù)尋求一個(gè)解決方法。
????????通常我們可以想到的一個(gè)方法是當(dāng)從A頁面跳轉(zhuǎn)至B頁面的時(shí)候?qū)⑿枰獋鬟f的大對(duì)象賦值給A頁面的一個(gè)靜態(tài)變量,在B頁面去取A頁面的值。這種方式簡單卻有很多問題,比如可能會(huì)有很多其他頁面訪問B頁面這會(huì)導(dǎo)致靜態(tài)變量管理混亂,而且如果在組件化開發(fā)的過程中,需要進(jìn)行組件間跳轉(zhuǎn)的時(shí)候只能把這種靜態(tài)變量寫在BaseLibrary中,這顯然是不夠友好的。
????????我們稍加處理做一個(gè)簡單的封裝。++參考:《Android工程化最佳實(shí)踐》++
step1: 創(chuàng)建對(duì)象的緩存區(qū),我們使用單例模式
public class ModelStorage {
private Map<Integer, Model> map = new ArrayMap<>();
public static ModelStorage getInstance(){
return SingletonHolder.instance;
}
private static class SingletonHolder{
private static final ModelStorage instance = new ModelStorage();
}
public int putModel(Model model){
if(map.containsValue(model)){
for(Map.Entry<Integer,Model> entry:map.entrySet()){
if(entry.getValue() == model){
return entry.getKey();
}
}
return 0;
}else{
int index = map.size();
map.put(index,model);
return index;
}
}
public Model getModel(int key){
if(map.size() == 0){
return null;
}else{
return map.remove(key);
}
}
}
step2:創(chuàng)建需要序列化傳遞對(duì)象的基類
public abstract class Model implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
int index= ModelStorage.getInstance().putModel(this);
dest.writeInt(index);
}
public static final Creator<Model> CREATOR = new Creator<Model>() {
@Override
public Model createFromParcel(Parcel in) {
int index = in.readInt();
return ModelStorage.getInstance().getModel(index);
}
@Override
public Model[] newArray(int size) {
return new Model[size];
}
};
@Override
public int describeContents() {
return 0;
}
}
????????就這樣簡單的兩個(gè)類我們就完成了封裝,可以看到在Model中序列化了一個(gè)int值。下面我們來看一個(gè)簡單的使用示例:
- 將想要序列化的類繼承Model
public class User extends Model {
//注意這里不需要將name和age序列化存儲(chǔ)
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
- 存取的方式如常規(guī)使用
intent.putExtra("key",new User("1111",12));
User user = getIntent().getParcelableExtra("key");
????????通過以上方式的封裝,可以看到無論需要序列化傳遞的對(duì)象有多大,在傳值的時(shí)候只是傳遞了一個(gè)“int”而已。使用該這種方法時(shí)需要注意的一點(diǎn)是在數(shù)據(jù)的接收頁面只能使用getIntent()獲取一次該對(duì)象的值,因?yàn)槲覀冊(cè)谌⊥暌淮沃岛蟊銓⒃搶?duì)象從緩存區(qū)移除了。