Android Parcelableインタフェース


1、Parcelableを実現するのはシーケンス化のためです.では、なぜシーケンス化するのですか.
1)オブジェクトを永続的に保存し、オブジェクトのバイトシーケンスをローカルファイルに保存する.
2)シーケンス化されたオブジェクトによってネットワークにオブジェクトを渡す.
3)シーケンス化によりプロセス間でオブジェクトを渡す.
2、シーケンス化の実現方法
Androidでシーケンス化を実現するには2つの選択肢があります.1つはSerializableインタフェース(JavaSE自体がサポートしています)を実現することです.1つはParcelableインタフェース(Android特有の機能で、Serializableインタフェースを実現するよりも効率的(10倍程度高く)、Intentデータ転送にもプロセス間通信(IPC))にも使用できます.Serializableインタフェースを実装するのは非常に簡単で、宣言すればいいのですが、Parcelableインタフェースを実装するのは少し複雑ですが、効率が高いので、この方法で性能を向上させることをお勧めします.
注:AndroidでIntentがオブジェクトを渡すには2つの方法があります.1つはBundleです.putSerializable(Key,Object)、もう一つはBundle.putParcelable(Key,Object).もちろん,これらのObjectには一定の条件があり,前者はSerializableインタフェースを実現し,後者はParcelableインタフェースを実現している.
3、シーケンス化方法の選択の原則
1)メモリを使用する場合、ParcelableはSerializableより性能が高いので、Parcelableを使用することをお勧めします.
2)Serializableはシーケンス化の際に大量の一時変数を発生させ,頻繁なGCを引き起こす.
3)Parcelableはデータをディスクに保存する場合に使用できない.なぜなら、Parcelableはデータの持続性が外部で変化する場合によく保証できないからである.Serializableは非効率ですが、この場合はSerializableを使用することをお勧めします.
4、シーンの適用
複数の部品(ActivityまたはService)の間でIntentを介していくつかのデータを渡す必要があります.単純なタイプ(数字、文字列など)はIntentに直接入れることができます.複雑なタイプはParcelableインタフェースを実装する必要があります.
5、Parcelableインタフェース定義
public interface Parcelable 
{
    //      ,    0   ;
    public int describeContents();
    //      ,  。               Parcel .           Parcel    ,   parcel      。
    public void writeToParcel(Parcel dest, int flags);
    //    ,     Parcel        Parcelable       。              ,           ,            
    //             ,    Creator    ,                      
    public interface Creator<T> 
    {
           // Parcel          ,   Parcelable       。
           public T createFromParcel(Parcel source);
           //       T,   size   ,    (return new T[size])  。                 。
           public T[] newArray(int size);
    }
}

6、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();
     }
 }

7、Serializable実現とParcelabel実現の違い
1)Serializableの実装は,implements Serializableのみでよい.これはオブジェクトにタグを付けるだけで、自動的にシーケンス化されます.
2)Parcelabelの実装には、implements Parcelabelだけでなく、クラスに静的メンバー変数CREATORを追加する必要がある.Creatorインタフェース.
3)SerializableはIO読み書きを使用してハードディスクに格納されているが、Parcelableは直接メモリに読み書きされており、メモリの読み書き速度は通常IO読み書きよりも大きいことが明らかであるため、Androidでは通常Parcelableが優先される.
両者のコード比較:
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();
    }
}