后面咱们晓得了启动activity的时候能够传递一些参数。Activity的跳转时能够传递Parcelable对象。
Parcelable对象和Serializable不一样。实现了Parcelable接口的类并不会被零碎序列化。
接下来咱们用一个例子看看如何应用这一接口。
应用例子
先筹备数据,而后传送Parcelable对象。
数据筹备
先设计一个类实现Parcelable接口。后面咱们应用Serializable的时候,类只有实现Serializable接口即可,不须要额定的操作。但用Parcelable接口会须要开发者多做一些工作。
Parcelable接口在android.os
包里,与Serializable不同。咱们必须明确意识这一点。
官网给出的一个应用例子。
<code class="java">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 in
和writeToParcel
办法。
官网例子中,公有结构器接管一个Parcel对象,而后从中读出一个int。而writeToParcel
办法中,把mData写入Parcel对象中。
这写入和读出操作就是咱们开发者须要特地关怀的中央。
之前应用intent.putExtra办法的时候会传入一个String类型的key(键),用于标示传入的数据。
但在官网的例子中,咱们只看到了一个int。而writeInt办法也没有指定key。零碎如何辨别出各个参数呢?
咱们自定义一个类DataParcel
,实现Parcelable
接口。as主动在外面生成了CREATOR。
<code class="java"> 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。
<code class="java">DataParcel dataParcel = new DataParcel(100, "s1", "s2", "扭转这个字符串看看是否被传递"); intent.putExtra(SendParamsDemo.K_PARCEL, dataParcel);
被关上的Activity接管传入的对象。
<code class="java">DataParcel dataParcel = intent.getParcelableExtra(K_PARCEL);
log中打印登程送和传入的对象信息。
<code class="log">D/rustAppMainActivity: goSendParamsDemo: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d8ce985 D/rustAppMainActivity: goSendParamsDemo: parcel obj: number: 100, str1: s1, str2: s2, noSave: 扭转这个字符串看看是否被传递 D/rustAppSendParamsDemo: gotInput: parcel obj: com.rustfisher.tutorial2020.act.DataParcel@d90a3a6 D/rustAppSendParamsDemo: gotInput: number: 100, str1: s1, str2: s2, noSave: [不传送的字符串]
从log中咱们能够看出,发送的对象和接管到的对象并不是同一个对象。但咱们指定的那3个属性是雷同的。
总结
至此,咱们理解了如何应用Parcelable这个接口。
Parcel和Parcelable是Android IPC中应用到的容器和工具。大家能够理解一下Binder机制
个别认为,一般状况下Parcelable性能上会优于Serializable。
Serializable波及到序列化,零碎会通过反射的办法来获取信息。相对而言比拟耗资源。
Parcel并不波及序列化机制。它是为了高性能IPC传输设计的。因而,Parcel并不适宜用来永久化存储数据。
理论工作中,咱们能够依据业务须要,综合开发工夫老本和利用性能要求,来抉择应用Parcelable或者Serializable。
- 示例代码
- Android Activity 传递Parcelable对象