Android数据传输之Parcelable

1.Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。

接口的源码如下:

public interface Parcelable {
    //内容描述接口,基本不用管
    public int describeContents();
    //写入接口函数,打包
    public void writeToParcel(Parcel dest, int flags);
     //读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入。
    //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。
    public interface Creator<T> {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
    }
}

2.类的写法:

package com.ysl.myandroidbase.bean;

import android.os.Parcel;
import android.os.Parcelable;

public class Cat implements Parcelable {
    public String name;
    public int age;

    public Cat() {
    }

    public Cat(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }

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

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

主要是要重写describeContents()、writeToParcel(Parcel dest, int flags)方法。

CREATOR:

/**
     * public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。
     * 重写接口中的两个方法:
     * createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,
     * newArray(int size) 创建一个类型为T,长度为size的数组,供外部类反序列化本类数组使用。
     */
    public static final Creator<Cat> CREATOR = new Creator<Cat>() {
        /**
         * 从序列化后的对象中创建原始对象
         */
        @Override
        public Cat createFromParcel(Parcel source) {
            return new Cat(source);
        }
        /**
         * 创建指定长度的原始对象数组
         */
        @Override
        public Cat[] newArray(int size) {
            return new Cat[size];
        }
    };

3.Intent数据传输:

发送数据:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                Bundle bundle = new Bundle();
                Cat cat = new Cat();
                cat.name = "tom";
                cat.age = 1;
                bundle.putParcelable("cat", cat);
                intent.putExtras(bundle);
                startActivity(intent);

接收数据:

Cat cat = getIntent().getParcelableExtra("cat");
        TextView tv3 = findViewById(R.id.tv3);
        tv3.setText(cat.name+"_"+cat.age);

4.Parcelable需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义。

Parcelable的性能,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,进程间的数据传输。但写法稍微复杂,并且因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化,只推荐内存数据的传输。

5.AndroidStudio使用parcelable插件

安装好插件以后,写好类以及要使用的字段:

package com.ysl.myaidl.bean;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

public class ParcelableBean implements Parcelable {
    String aString;
    int aInt;
    double aDouble;
    HashMap<String, String> aHashMap;
    ArrayList<String> aArrayList;
    DemoAnotherClass anotherClass;

    class DemoAnotherClass{
        ConcurrentHashMap<String, String> aConcurrentHashMap;
    }
}

选中类名,按alt+insert键,选择最下面的parcelable,立马生成代码。

package com.ysl.myaidl.bean;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

public class ParcelableBean implements Parcelable {
    String aString;
    int aInt;
    double aDouble;
    HashMap<String, String> aHashMap;
    ArrayList<String> aArrayList;
    DemoAnotherClass anotherClass;

    static class DemoAnotherClass implements Parcelable{
        ConcurrentHashMap<String, String> aConcurrentHashMap;

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

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeSerializable(this.aConcurrentHashMap);
        }

        public DemoAnotherClass() {
        }

        protected DemoAnotherClass(Parcel in) {
            this.aConcurrentHashMap = (ConcurrentHashMap<String, String>) in.readSerializable();
        }

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

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.aString);
        dest.writeInt(this.aInt);
        dest.writeDouble(this.aDouble);
        dest.writeSerializable(this.aHashMap);
        dest.writeStringList(this.aArrayList);
        dest.writeParcelable(this.anotherClass, flags);
    }

    public ParcelableBean() {
    }

    protected ParcelableBean(Parcel in) {
        this.aString = in.readString();
        this.aInt = in.readInt();
        this.aDouble = in.readDouble();
        this.aHashMap = (HashMap<String, String>) in.readSerializable();
        this.aArrayList = in.createStringArrayList();
        this.anotherClass = in.readParcelable(DemoAnotherClass.class.getClassLoader());
    }

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

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

内部类要改成static的,而且也要实现parcelable接口,否则会报错。

参考:https://blog.csdn.net/cheyiliu/article/details/46553129

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值