后面咱们晓得了启动activity的时候能够传递一些参数。Activity的跳转时能够传递Parcelable对象。

Parcelable对象和Serializable不一样。实现了Parcelable接口的类并不会被零碎序列化。
接下来咱们用一个例子看看如何应用这一接口。

应用例子

先筹备数据,而后传送Parcelable对象。

数据筹备

先设计一个类实现Parcelable接口。后面咱们应用Serializable的时候,类只有实现Serializable接口即可,不须要额定的操作。但用Parcelable接口会须要开发者多做一些工作。

Parcelable接口在android.os包里,与Serializable不同。咱们必须明确意识这一点。
官网给出的一个应用例子。

public class MyParcelable implements Parcelable {      private int mData;       public int describeContents() {          return 0;      }       public void writeToParcel(Parcel out, int flags) {          out.writeInt(mData);      }       public static final Parcelable.Creator<MyParcelable> CREATOR              = new Parcelable.Creator<MyParcelable>() {          public MyParcelable createFromParcel(Parcel in) {              return new MyParcelable(in);          }           public MyParcelable[] newArray(int size) {              return new MyParcelable[size];          }      };       private MyParcelable(Parcel in) {          mData = in.readInt();      }}

能够看到,强制应用了一个Parcelable.Creator对象。外面的办法咱们临时不论也不批改。
重点关注公有结构器MyParcelable(Parcel inwriteToParcel办法。

官网例子中,公有结构器接管一个Parcel对象,而后从中读出一个int。而writeToParcel办法中,把mData写入Parcel对象中。
这写入和读出操作就是咱们开发者须要特地关怀的中央。

之前应用intent.putExtra办法的时候会传入一个String类型的key(键),用于标示传入的数据。
但在官网的例子中,咱们只看到了一个int。而writeInt办法也没有指定key。零碎如何辨别出各个参数呢?

咱们自定义一个类DataParcel,实现Parcelable接口。as主动在外面生成了CREATOR

import android.os.Parcel;import android.os.Parcelable;public class DataParcel implements Parcelable {    private int number;    private String str1;    private String str2;    private String noSave = "[不传送的字符串]";        // getter setter ...    public String info() {        return "number: "+number+", str1: "+str1+", str2: "+str2+", noSave: "+noSave;    }    protected DataParcel(Parcel in) {        number = in.readInt();        str1 = in.readString();        str2 = in.readString();    }    public DataParcel(int number, String str1, String str2, String noSave) {        this.number = number;        this.str1 = str1;        this.str2 = str2;        this.noSave = noSave;    }    public static final Creator<DataParcel> CREATOR = new Creator<DataParcel>() {        @Override        public DataParcel createFromParcel(Parcel in) {            return new DataParcel(in);        }        @Override        public DataParcel[] newArray(int size) {            return new DataParcel[size];        }    };    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(number);        dest.writeString(str1);        dest.writeString(str2);    }}

能够看到咱们有1个int和3个String。公开结构器须要传入这4个属性。

writeToParcel办法中,按程序写入了int和2个String。公有结构器中,按程序读出了int和2个String。

noSave并没有被写入和读出。拿来做比照。info()办法是拿来打印信息的。

传送Parcelable对象

当初咱们的类曾经设计好了,传送对象试试。

把DataParcel对象交给intent。

DataParcel dataParcel = new DataParcel(100, "s1", "s2", "扭转这个字符串看看是否被传递");intent.putExtra(SendParamsDemo.K_PARCEL, dataParcel);

被关上的Activity接管传入的对象。

DataParcel dataParcel = intent.getParcelableExtra(K_PARCEL);

log中打印登程送和传入的对象信息。

D/rustAppMainActivity: goSendParamsDemo: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d8ce985D/rustAppMainActivity: goSendParamsDemo: parcel obj: number: 100, str1: s1, str2: s2, noSave: 扭转这个字符串看看是否被传递D/rustAppSendParamsDemo: gotInput: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d90a3a6D/rustAppSendParamsDemo: gotInput: number: 100, str1: s1, str2: s2, noSave: [不传送的字符串]

从log中咱们能够看出,发送的对象和接管到的对象并不是同一个对象。但咱们指定的那3个属性是雷同的。

总结

至此,咱们理解了如何应用Parcelable这个接口。
ParcelParcelable是Android IPC中应用到的容器和工具。大家能够理解一下Binder机制

个别认为,一般状况下Parcelable性能上会优于Serializable
Serializable波及到序列化,零碎会通过反射的办法来获取信息。相对而言比拟耗资源。
Parcel并不波及序列化机制。它是为了高性能IPC传输设计的。因而,Parcel并不适宜用来永久化存储数据。

理论工作中,咱们能够依据业务须要,综合开发工夫老本和利用性能要求,来抉择应用Parcelable或者Serializable

  • 示例代码
  • Android Activity 传递Parcelable对象