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

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

作者: xu_pan | 来源:发表于2019-09-25 17:35 被阅读0次

            我们知道在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()获取一次该对象的值,因为我们在取完一次值后便将该对象从缓存区移除了。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/kuxjyctx.html