Android:使用Parcelable接口在跳转Activity时传递数据以及错误信息 Parcel: unable to marshal value 的解决

Parcelable是Android系统中特有的接口,它不像Serializable接口那样是Java语言自带的。Intent也使用Parcelable方式来传递对象的数据,不过它不同于Serializable方式将对象进行序列化,而是通过将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的传递数据类型。

传递对象中没有List类型数据

对自定义的类实现Parcelable接口

注意自定义的类一定要是静态的,否则怎么改都会报错,目前我也不知道为什么,这么用就对了~

public static class Person implements Parcelable{

        private String name;
        private int age;

        public void Person(){}

        protected Person(Parcel in) {
            name = in.readString();
            age  = in.readInt();
        }

        public static final Creator<Person> CREATOR = new Creator<Person>() {
            @Override
            public Person createFromParcel(Parcel in) {
                return new Person(in);
            }

            @Override
            public Person[] newArray(int size) {
                return new Person[size];
            }
        };

        public Person() {

        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeInt(age);
        }
        
        /*
        	Setter and Getter
        	*/
    }

MainActivity

Intent intent = new Intent(this, SecondActivity.class);
Bundle bundle = new Bundle();

Person person = new Person();
person.setAge(144);
person.setName("lzh");

bundle.putParcelable("data", person);
intent.putExtras(bundle);

startActivity(intent);

SecondActivity

//获取数据
Person person = getIntent().getParcelableExtra("data");

传递对象中有List类型数据

以菜品类为例,注意和上面没有List类型数据的情况不同。

如果List类型中的类是自定义的,需要对自定义的类也实现Parelable接口,否则就会出现 Parcel: unable to marshal value 的错误。

同时需要在重写createFromParcel方法。

DishData.java

public class DishData implements Parcelable {
    public class DishData implements Parcelable {
    private int id;
    private String name;
    private String peoplenum;
    private String preparetime;
    private String cookingtime;
    private String content;
    private String pic;
    private String tag;
    private List<Material> material = new ArrayList<>();
    private List<Process> process = new ArrayList<>();

    public DishData(){}


    protected DishData(Parcel in) {
        id = in.readInt();
        name = in.readString();
        peoplenum = in.readString();
        preparetime = in.readString();
        cookingtime = in.readString();
        content = in.readString();
        pic = in.readString();
        tag = in.readString();
        material = in.readArrayList(getClass().getClassLoader());
        process = in.readArrayList(getClass().getClassLoader());
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeString(peoplenum);
        dest.writeString(preparetime);
        dest.writeString(cookingtime);
        dest.writeString(content);
        dest.writeString(pic);
        dest.writeString(tag);
        dest.writeList(material);
        dest.writeList(process);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<DishData> CREATOR = new Creator<DishData>() {
        @Override
        public DishData createFromParcel(Parcel in) {
            DishData data = new DishData();
            data.id = in.readInt();
            data.name = in.readString();
            data.peoplenum = in.readString();
            data.preparetime = in.readString();
            data.cookingtime = in.readString();;
            data.content = in.readString();
            data.pic = in.readString();
            data.tag = in.readString();
            
            data.material = new ArrayList<>();
            in.readList(data.material, getClass().getClassLoader());

            data.process = new ArrayList<>();
            in.readList(data.process, getClass().getClassLoader());
            
            return data;
        }

        @Override
        public DishData[] newArray(int size) {
            return new DishData[size];
        }
    };

    /*
    	Setter and Getter
    	*/
}

Material.java

public class Material implements Parcelable {
    private String mname;   
    private String amount;  

    protected Material(Parcel in) {
        mname = in.readString();
        amount = in.readString();
    }

    public static final Creator<Material> CREATOR = new Creator<Material>() {
        @Override
        public Material createFromParcel(Parcel in) {
            return new Material(in);
        }

        @Override
        public Material[] newArray(int size) {
            return new Material[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(mname);
        parcel.writeString(amount);
    }
    
    /*
    	Setter and getter
   		*/
}

MainActivity传递数据

Intent intent = new Intent(getActivity(), DishActivity.class);
Bundle bundle = new Bundle();

DishData data = new DishData();

data.setId(id);
data.setName(name);
// ...

bundle.putParcelable("dishData", data);
intent.putExtras(bundle);

//跳转到DishActivity
startActivity(intent);

DishActivity获取数据

DishData dishData = getIntent().getParcelableExtra("dishData");
Log.i(TAG, "onCreate: material.size = "+dishData.getMaterial().size());
上一篇:Android高级架构进阶之数据传输与序列化,androidstudio物联网


下一篇:使用Parcel打包TS代码,这可能是学习TS阶段最简单的打包工具