AndroidのSerializableとParcelableインタフェース


人を知る者は智なり、自覚する者は明なり.胜つ者は力强く、胜つ者は强い.--老子
最近Activity間のデータ転送のタイプをまとめると、Androidではオブジェクトを転送する必要がある場合にSerializableやParcelableインタフェースを実現するのが一般的であることが知られていますが、書くだけで、その内在的な原理が少しも理解できず、複数のブログを読んで自ら検証した後、SerializableとParcelableの原理と使用をまとめることにしました.誤りがあれば指摘を歓迎し、疑問があれば伝言を歓迎する.私は最初の時間に答えたり修正したりします.
 
一、Serializableはシーケンス化を意味し、シーケンス化と逆シーケンス化とは何ですか.
オブジェクトのシーケンス化:オブジェクトをバイトシーケンスに変換するプロセスをオブジェクトのシーケンス化と呼びます.
逆シーケンス化:バイトシーケンスをJavaオブジェクトに復元するプロセス.
シーケンス化を明確にするには、Javaオブジェクト、バイトシーケンス、ストレージの3つの点を明らかにする必要があります.
①Javaオブジェクト
Javaオブジェクトには変数とメソッドが含まれます.ただし,シーケンスと逆シーケンス化はJava変数のみを処理し,メソッドを処理せず,シーケンスと逆シーケンス化はデータのみを処理する.
②バイトシーケンスとは、実は連続して並ぶ複数文字のシーケンスであり、例えば「asdsdsfsdfsdff」
③記憶
文字列は、ハードディスク(HDD)でもメモリでも1つの場所に保存する必要があります.
簡単に言えば、シーケンス化は現在のオブジェクト情報を保存します.逆シーケンス化は正反対の操作です.
二、どうしてシーケンス化を使うのですか.
シーケンス化とは何かを知ると、なぜシーケンス化を使用するのかと聞かれるかもしれません.何の役に立つの?
シーケンス化の定義から、オブジェクトをストリームに変換し、ローカルに保存することがわかります.シーケンス化には主に以下の用途があります.
(1)オブジェクトを永続的に保存し、オブジェクトのバイトシーケンスをローカルファイルに保存する.
(2)シーケンス化されたオブジェクトによってネットワークにオブジェクトを渡す.
(3)プロセス間でシーケンス化によってオブジェクトを渡す(androidがシーケンス化によってオブジェクトを渡すなど).
三、JavaオブジェクトとJavaオブジェクトのシーケンス化の違い?
Javaオブジェクトが存在する前提は、JVMの実行中に存在する必要があります.JVMが実行されていない場合や、他のマシンJVM上で指定されたJavaオブジェクトを取得したい場合は、既存のJavaオブジェクトのメカニズムでは完了できません.Javaオブジェクトとは異なり、Javaオブジェクトに対してシーケンス化操作を行う場合、Javaオブジェクト情報を記憶媒体に保存することが原理であるため、以上のJavaオブジェクトが存在し得ない2つの場合でもJavaオブジェクトを使用することができる.
四、シーケンス化の実現方法
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インタフェースを実現している.
2つのシーケンス化方法の比較:
①Serializable、簡単で使いやすく、効率が低い
serializableの魅力的な点は、クラスとその属性に対してSerializableインタフェースを実装するだけでいいことです.Serializableインタフェースは、メソッドを実装する必要がなく、Javaがこのオブジェクトを効率的にシーケンス化することを意味する識別インタフェースです.
この方法の欠点は,反射を用い,シーケンス化の過程が遅いことである.このメカニズムは、シーケンス化時に多くの一時オブジェクトを作成し、ゴミ回収をトリガーしやすい.
②Parcelable、速度至上、コード量の読み取りとメンテナンスが容易ではない
Googleエンジニアによると、これらのコードは特に速く動作します.理由の1つは,反射を用いて推定する必要がなく,シーケンス化の過程を明確に知っていることである.また、シーケンス化をより迅速に行うためには、オブジェクトのコードも高度に最適化する必要があります.したがって,Parcelableの実現は容易ではないことは明らかである.Parcelableインタフェースを実装するには、大量のテンプレートコードを書く必要があり、オブジェクトコードの読み取りとメンテナンスが困難になります.
について
Parcelable比
Serializableの実行速度が遅い比較詳細はこのブログを参照してくださいhttp://greenrobot.me/devpost/android-parcelable-serializable/
Serializableの役割は、オブジェクトの属性をローカルファイル、データベース、ネットワークストリーム、rmiに保存してデータ転送を容易にするためであり、もちろん、この転送はプログラム内でも2つのプログラム間でもよい.一方、AndroidのParcelableの設計の目的は、Serializableの効率が遅すぎるため、プログラム内の異なるコンポーネント間および異なるAndroidプログラム間(AIDL)で効率的にデータを転送するために設計され、これらのデータはメモリにのみ存在し、ParcelableはIBinder通信によるメッセージの担体である.Parcelableの設計の初心からParcelableの速度が比較的速いことも見えますが、どのようなシーケンス化方式を使用するかをどのように選択しますか?
優れたソフトウェアエンジニアになりたい場合は、Parcelableを実現するのに多くの時間がかかります.これは、オブジェクトのシーケンス化プロセスが10倍以上速く、リソースが少ないためです.
五、Parcelableインタフェースの定義
public interface Parcelable
    {
        //      ,     
        public int describeContents();
        //      ,  
        public void writeToParcel(Parcel dest, int flags);
        //    ,     Parcel         Parcelable       。              ,           ,          <span style="white-space:pre">	</span>    <span style="white-space:pre">	</span>
        //             ,    Creator    ,                      
        public interface Creator<T>
        {
               public T createFromParcel(Parcel source);
               public T[] newArray( int size);
        }
     }

六、応用例
①Parcelable実装Parcelableは大きく分けて4つのステップに分けられる:1)implements Parcelable 2)writeToParcelメソッドを書き換え、あなたのオブジェクトを1つのParcelオブジェクトにシーケンス化する.すなわち、クラスのデータを外部から提供された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])外部クラスが本クラスの配列を逆シーケンス化するために使用します.
Parcelableの実装手順から、次のようになります.
オブジェクトをwriteToParcelでParceldオブジェクトにマッピングし、createFromParcelでParcelオブジェクトをオブジェクトにマッピングします.Parcelをストリームと見なすこともでき、writeToParcelを通じてオブジェクトをストリームに書き、createFromParcelを通じてストリームからオブジェクトを読み取ることができますが、このプロセスは私たちが実現する必要があります.
だから書く順番と読む順番は

.
Parcelableインタフェースを実装したクラスを作成
Bookクラス
package com.example.progressbar;
import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {
     
private String name;     
private int price;
private String author;
     
public Book() {}
     
public Book(String name, int price, String author) {

     this.name = name;
     this.price = price;
     this.author = author;
}
     
public String getName() {
      return name;
 }
     
public void setName(String name) {

     this.name = name;
}
     
public int getPrice() {
     return price;
}
public void setPrice(int price) {

     this.price = price;
}
public String getAuthor() {
     return author;
}
    
public void setAuthor(String author) {
      this.author = author;
}
  @Override
public int describeContents() {
      return 0;
}
//                Parcel 。
@Override
public void writeToParcel(Parcel parcel, int i) {
     parcel.writeString(this.name);
     parcel.writeInt(this.price);
     parcel.writeString(this.author);
}
  
public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
//     Book[i]               
@Override
public Book[] newArray(int i) {        
     return new Book[i];
}
         
@Override       
public Book createFromParcel(Parcel parcel) {
//  Parcel       Book  
return new Book(parcel.readString(),parcel.readInt(),parcel.readString());
           }
     };
}

StudentクラスインプリメンテーションSerializableを作成し、Serializableを実装するのは比較的簡単でimplements Serializableだけでよい.これはオブジェクトにタグを付けるだけで、自動的にシーケンス化されます.
Studentクラス
packagecom.example.progressbar;
import java.io.Serializable;
publicclassStudent implements Serializable { 
private static final long serialVersionUID = 1L;
private String name;  
private int age;
private String sex;      
   public Student(){}
   public Student(String name,int age,String sex){          
       this.name=name;           
       this.age=age;          
       this.sex=sex;
}
  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;
}
 public String getSex() {           
     return sex;
}
  public void setSex(String sex) {
      this.sex = sex;
   }
}

はい、このブログはここまでです.見終わったら、一言を残してください.あなたの支持は私の前進の原動力です.