Android
Parcelable
Поиск…
Вступление
Parcelable - это специфический для Android интерфейс, где вы сами реализуете сериализацию. Он был создан гораздо эффективнее, чем Serializable, и чтобы обойти некоторые проблемы со схемой сериализации Java по умолчанию.
замечания
Важно помнить, что порядок, в котором вы пишете поля в парцеллу, ДОЛЖЕН БЫТЬ ОЖИДАЕМОЙ ЗАКАЗ, что вы читаете их из посылки при создании своего настраиваемого объекта.
Порочный интерфейс имеет строгий предел размера 1 МБ. Это означает, что любой объект или комбинации объектов, которые вы помещаете в посылку, которая занимает более 1 МБ пространства, будет повреждена с другой стороны. Это может быть трудно обнаружить, поэтому имейте в виду, какие объекты вы планируете сделать обоснованными. Если они имеют большие деревья зависимостей, рассмотрите другой способ передачи данных.
Создание настраиваемого объекта.
/**
* Created by Alex Sullivan on 7/21/16.
*/
public class Foo implements Parcelable
{
private final int myFirstVariable;
private final String mySecondVariable;
private final long myThirdVariable;
public Foo(int myFirstVariable, String mySecondVariable, long myThirdVariable)
{
this.myFirstVariable = myFirstVariable;
this.mySecondVariable = mySecondVariable;
this.myThirdVariable = myThirdVariable;
}
// Note that you MUST read values from the parcel IN THE SAME ORDER that
// values were WRITTEN to the parcel! This method is our own custom method
// to instantiate our object from a Parcel. It is used in the Parcelable.Creator variable we declare below.
public Foo(Parcel in)
{
this.myFirstVariable = in.readInt();
this.mySecondVariable = in.readString();
this.myThirdVariable = in.readLong();
}
// The describe contents method can normally return 0. It's used when
// the parceled object includes a file descriptor.
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(myFirstVariable);
dest.writeString(mySecondVariable);
dest.writeLong(myThirdVariable);
}
// Note that this seemingly random field IS NOT OPTIONAL. The system will
// look for this variable using reflection in order to instantiate your
// parceled object when read from an Intent.
public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>()
{
// This method is used to actually instantiate our custom object
// from the Parcel. Convention dictates we make a new constructor that
// takes the parcel in as its only argument.
public Foo createFromParcel(Parcel in)
{
return new Foo(in);
}
// This method is used to make an array of your custom object.
// Declaring a new array with the provided size is usually enough.
public Foo[] newArray(int size)
{
return new Foo[size];
}
};
}
Объект Parcelable, содержащий другой объект Parcelable
Пример класса, содержащего класс:
public class Repository implements Parcelable {
private String name;
private Owner owner;
private boolean isPrivate;
public Repository(String name, Owner owner, boolean isPrivate) {
this.name = name;
this.owner = owner;
this.isPrivate = isPrivate;
}
protected Repository(Parcel in) {
name = in.readString();
owner = in.readParcelable(Owner.class.getClassLoader());
isPrivate = in.readByte() != 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeParcelable(owner, flags);
dest.writeByte((byte) (isPrivate ? 1 : 0));
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Repository> CREATOR = new Creator<Repository>() {
@Override
public Repository createFromParcel(Parcel in) {
return new Repository(in);
}
@Override
public Repository[] newArray(int size) {
return new Repository[size];
}
};
//getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
public boolean isPrivate() {
return isPrivate;
}
public void setPrivate(boolean isPrivate) {
this.isPrivate = isPrivate;
}
}
Владелец - просто нормальный класс.
Использование Enums with Parcelable
/**
* Created by Nick Cardoso on 03/08/16.
* This is not a complete parcelable implementation, it only highlights the easiest
* way to read and write your Enum values to your parcel
*/
public class Foo implements Parcelable {
private final MyEnum myEnumVariable;
private final MyEnum mySaferEnumVariableExample;
public Foo(Parcel in) {
//the simplest way
myEnumVariable = MyEnum.valueOf( in.readString() );
//with some error checking
try {
mySaferEnumVariableExample= MyEnum.valueOf( in.readString() );
} catch (IllegalArgumentException e) { //bad string or null value
mySaferEnumVariableExample= MyEnum.DEFAULT;
}
}
...
@Override
public void writeToParcel(Parcel dest, int flags) {
//the simple way
dest.writeString(myEnumVariable.name());
//avoiding NPEs with some error checking
dest.writeString(mySaferEnumVariableExample == null? null : mySaferEnumVariableExample.name());
}
}
public enum MyEnum {
VALUE_1,
VALUE_2,
DEFAULT
}
Это предпочтительнее (например), используя порядковый номер, потому что вставка новых значений в ваш перечисление не повлияет на ранее сохраненные значения