Android Intent传递大量数据造成页面卡顿,闪退的解决

2019-09-25  本文已影响0人  xu_pan

        我们知道在Activity间使用Intent传递List含有大量序列化的对象的时候,或者传递较大bitmap等较大量数据的时候会引起页面卡顿。而且Android本身也限制了能够传递的数据大小在1MB左右。这就要求我们不得不为传输大量数据寻求一个解决方法。

        通常我们可以想到的一个方法是当从A页面跳转至B页面的时候将需要传递的大对象赋值给A页面的一个静态变量,在B页面去取A页面的值。这种方式简单却有很多问题,比如可能会有很多其他页面访问B页面这会导致静态变量管理混乱,而且如果在组件化开发的过程中,需要进行组件间跳转的时候只能把这种静态变量写在BaseLibrary中,这显然是不够友好的。

        我们稍加处理做一个简单的封装。++参考:《Android工程化最佳实践》++

step1: 创建对象的缓存区,我们使用单例模式
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:创建需要序列化传递对象的基类
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;
    }

}

        就这样简单的两个类我们就完成了封装,可以看到在Model中序列化了一个int值。下面我们来看一个简单的使用示例:

  1. 将想要序列化的类继承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;
    }
}
  1. 存取的方式如常规使用
intent.putExtra("key",new User("1111",12));

User user = getIntent().getParcelableExtra("key");

        通过以上方式的封装,可以看到无论需要序列化传递的对象有多大,在传值的时候只是传递了一个“int”而已。使用该这种方法时需要注意的一点是在数据的接收页面只能使用getIntent()获取一次该对象的值,因为我们在取完一次值后便将该对象从缓存区移除了。

上一篇下一篇

猜你喜欢

热点阅读