共计 3177 个字符,预计需要花费 8 分钟才能阅读完成。
后面咱们晓得了启动 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 in
和writeToParcel
办法。
官网例子中,公有结构器接管一个 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@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 对象