我们知道在Activity间使用Intent传递List含有大量序列化的对象的时候,或者传递较大bitmap等较大量数据的时候会引起页面卡顿。而且Android本身也限制了能够传递的数据大小在1MB左右。这就要求我们不得不为传输大量数据寻求一个解决方法。
通常我们可以想到的一个方法是当从A页面跳转至B页面的时候将需要传递的大对象赋值给A页面的一个静态变量,在B页面去取A页面的值。这种方式简单却有很多问题,比如可能会有很多其他页面访问B页面这会导致静态变量管理混乱,而且如果在组件化开发的过程中,需要进行组件间跳转的时候只能把这种静态变量写在BaseLibrary中,这显然是不够友好的。
我们稍加处理做一个简单的封装。++参考:《Android工程化最佳实践》++
step1: 创建对象的缓存区,我们使用单例模式
public class ModelStorage {
private Map 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 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:创建需要序列化传递对象的基类
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 CREATOR = new Creator() {
@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;
}
}
就这样简单的两个类我们就完成了封装,可以看到在Model中序列化了一个int值。下面我们来看一个简单的使用示例:
将想要序列化的类继承Model
public class User extends Model {
//注意这里不需要将name和age序列化存储
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
存取的方式如常规使用
intent.putExtra("key",new User("1111",12));
User user = getIntent().getParcelableExtra("key");
通过以上方式的封装,可以看到无论需要序列化传递的对象有多大,在传值的时候只是传递了一个“int”而已。使用该这种方法时需要注意的一点是在数据的接收页面只能使用getIntent()获取一次该对象的值,因为我们在取完一次值后便将该对象从缓存区移除了。