シーケンス化ParcelableとSerializableインタフェースの違い
一、ParcelableとSerializableインタフェースの概要
1.Parcelableインタフェース
Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
2.Parcelableを実現するのはシーケンス化のためです.では、なぜシーケンス化するのですか.
1)オブジェクトを永続的に保存し、オブジェクトのバイトシーケンスをローカルファイルに保存する.
2)シーケンス化されたオブジェクトによってネットワークにオブジェクトを渡す.
3)シーケンス化によりプロセス間でオブジェクトを渡す.
3.シーケンス化を実現する方法
Androidでシーケンス化を実現するには2つの選択肢があります.1つはSerializableインタフェース(JavaSE自体がサポートしています)を実現することです.1つはParcelableインタフェース(Android特有の機能で、Serializableインタフェースを実現するよりも効率的で、Intentデータ転送にも使用できますし、インターフェース通信(IPC)にも使用できます).Serializableインタフェースを実装するのは非常に簡単で、宣言すればいいのですが、Parcelableインタフェースを実装するのは少し複雑ですが、効率が高いので、この方法で性能を向上させることをお勧めします.
注:AndroidでIntentがオブジェクトを渡すには2つの方法があります.1つはBundleです.putSerializable(Key,Object)、もう一つはBundle.putParcelable(Key,Object).もちろん,これらのObjectには一定の条件があり,前者はSerializableインタフェースを実現し,後者はParcelableインタフェースを実現している.
4.シーケンス化方法の選択の原則
1)メモリを使用する場合、ParcelableはSerializableより性能が高いので、Parcelableを使用することをお勧めします.
2)Serializableはシーケンス化の際に大量の一時変数を発生させ,頻繁なGCを引き起こす.
3)Parcelableはデータをディスクに保存する場合に使用できない.なぜなら、Parcelableはデータの持続性が外部で変化する場合によく保証できないからである.Serializableは非効率ですが、この場合はSerializableを使用することをお勧めします.
5.シーンの適用
複数の部品(ActivityまたはService)の間でIntentを介していくつかのデータを渡す必要があります.単純なタイプ(数字、文字列など)はIntentに直接入れることができます.複雑なタイプはParcelableインタフェースを実装する必要があります.
6、Parcelableインタフェース定義
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);
}
}
7、Parcelableステップを実現する
1)implements Parcelable
2)writeToParcelメソッドを書き換え、あなたのオブジェクトを1つのParcelオブジェクトにシーケンス化します.つまり、クラスのデータを外部から提供されたParcelに書き込み、Parcelコンテナからデータを取得するために伝達するデータをパッケージ化して保存します.
3)describeContentsメソッド、コンテンツインタフェースの記述を書き換え、デフォルトでは0を返します.
4)静的内部オブジェクトCREATOR実装インタフェースParcelable.Creator
public static final Parcelable.Creator<T> CREATOR
注意:public static finalは1つも少なくできません.内部オブジェクトCREATORの名前も変更できません.すべて大文字でなければなりません.このインタフェースの2つの方法を書き直す必要があります:createFromParcel(Parcel in)はParcelコンテナから伝達データ値を読み出し、Parcelableオブジェクトにカプセル化して論理層に戻り、newArray(int size)はTタイプ、size長の配列を作成し、一言だけで(return new T[size])外部クラスが本クラスの配列を逆シーケンス化するために使用します.
簡単に言えば、writeToParcelでオブジェクトをParcelオブジェクトにマッピングし、createFromParcelでオブジェクトにマッピングします.Parcelをストリームと見なすこともでき、writeToParcelを通じてオブジェクトをストリームに書き、createFromParcelを通じてストリームからオブジェクトを読み取ることができますが、このプロセスはあなたが実現する必要があるので、書く順序と読む順序は一致しなければなりません.
コードは次のとおりです.
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();
}
}
8、Serializable実現とParcelabel実現の違い
1)Serializableの実装は,implements Serializableのみでよい.これはオブジェクトにタグを付けるだけで、自動的にシーケンス化されます.
2)Parcelabelの実装には、implements Parcelabelだけでなく、クラスに静的メンバー変数CREATORを追加する必要がある.Creatorインタフェース.
両者のコード比較:
1)Personクラスを作成し、Serializableを実現する
public class Person implements Serializable
{
private static final long serialVersionUID = -7060210544600464481L;
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
2)Bookクラスを作成し、Parcelableを実現する
public class Book implements Parcelable
{
private String bookName;
private String author;
private int publishDate;
public Book()
{
}
public String getBookName()
{
return bookName;
}
public void setBookName(String bookName)
{
this.bookName = bookName;
}
public String getAuthor()
{
return author;
}
public void setAuthor(String author)
{
this.author = author;
}
public int getPublishDate()
{
return publishDate;
}
public void setPublishDate(int publishDate)
{
this.publishDate = publishDate;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags)
{
out.writeString(bookName);
out.writeString(author);
out.writeInt(publishDate);
}
public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>()
{
@Override
public Book[] newArray(int size)
{
return new Book[size];
}
@Override
public Book createFromParcel(Parcel in)
{
return new Book(in);
}
};
public Book(Parcel in)
{
bookName = in.readString();
author = in.readString();
publishDate = in.readInt();
}
}
、Parcelablehe Serialiable
1)
、 、 ?(1)
: Java 。
: Java 。
(2)
:Java 、 、 。
1. Java ?
Java 。 Java , 。
2. ?
, , (Character) 。 , ( )。
《 - 》 , 《 - 》 。 1A165613246546
3.
, 。
: 。 。
、Java Java ?
Java JVM , JVM JVM Java , Java 。
Java , Java , Java , Java Java 。
2)Parcelablehe Serialiable
1、
Serializable 、 、 、rmi ,
Android Parcelable Serializable , Android (AIDL) , ,Parcelable IBinder 。
。
2、
Parcelable Serializable , , Parcelable, activity , Serializable , Serializable, android Parcelable , Parcelable
3、
Serializable, Serializable , id(serialVersionUID) 。 Parcelable writeToParcel、describeContents CREATOR , , 。
Parcelable
public class MyParcelable implements Parcelable {
private int mData;
private String mStr;
public int describeContents() {
return 0;
}
//
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
out.writeString(mStr);
}
// Parcelable
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();
mStr = in.readString();
}
}
上記からParcelの書き込みと読み出しの順序が一致していることが分かる.要素がlist読み出しの場合、まずnewのArrayListが入力される必要があります.そうしないと、ポインタ異常が報告されます.次のようになります.
list = new ArrayList<String>();
in.readStringList(list);
PS: ,read int long , , , 。
11-21 20:14:10.317: E/AndroidRuntime(21114): Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4126ed60: Unmarshalling unknown type code 3014773 at offset 164
4、
Serializable , Transient , writeObject、readObject