Intent転送オブジェクト

44457 ワード

目次

  • Serializable
  • 概要
  • 転送対象クラス実装Serializableインタフェース
  • 伝達対象
  • 完全切替Activityイニシエータコード
  • 宛先Activity受信対象
  • 完全切替Activityターゲット側コード
  • Parcelable
  • 概要
  • 実装手順
  • まとめ
  • 完全なActivity切替イニシエータコード
  • Activity切替先受信対象
  • 完全なActivity切替先方コード
  • SerializableとParcelableの簡単な比較
  • 同点
  • 相違点
  • まとめ
  • Serializable


    概要


     ライトコードについては,Intentを用いてActivity間でオブジェクトを伝達するが,最も簡単な方法は被伝達オブジェクトのクラスにSerializable空インタフェースを実現させることである. SerializableAndroid定義のインタフェースではなくjava.ioで定義されています.

    転送対象クラス実装Serializableインタフェース

    import java.io.Serializable;
    
    public class Person implements Serializable {
        private String name;
        private double height;
        
        public void setName(String name) {
            this.name=name;
        }
        public void setHeight(double height) {
            this.height=height;
        }
        public String getName() {
            return name;
        }
        public double getHeight() {
            return height;
        }
    }
    

    Serializableインタフェースを使用するには、java.io.Serializableを事前にインポートする必要があります.

    オブジェクトを渡す

    Person person=new Person();
    person.name="Lishaoyin";
    person.height="1.70";
    
    Intent intent=new Intent(this,TargetActivity.class);
    intent.putExtra("Lishaoyin",person);
    startActivity(intent);
    

     説明:この時点で使用されるputExtra()のバージョンは次のとおりです.
    public Intent putExtra(String name,Serializable value)
    

     特に注意:被伝達オブジェクトが他のクラスのオブジェクトを参照している場合、被引用オブジェクトのクラスもSerializableインタフェースを実現しなければならない.

    Activityイニシエータコードの完全な切り替え

    CurrentActivity.java
    import...
    import java.io.Serializable
    
    public class CurrentActivity extends Activity
                              implements View.OnClickListener {
        
        private Person person=new Person();
                       
        @Override                   
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //load currentActivity.xml
            setContentView(R.layout.currentActivity);  
            
            Button btn_1=(Button)findviewById(R.id.btn_1);
            btn_1.setOnClickListener(this);
            
            person.setName("Lishaoyin");
            person.setHeight(1.70);
        }
        
        @Override
        protected onClick(View v) {
            Intent intent=new Intent(this,TargetActivity.class);
            intent.putExtra("Lishaoyin",person);
            startActivity(intent);   //launch TargetActivity
        }
    }
    
    Person.java
    //implements Serializable interface
    public class Person implements Serializable {
        private String name;
        private double height;
        public void setName(String name) {
            this.name=name;
        }
        public void setHeight(double height) {
            this.height=height;
        }
        public String getName() {
            return name;
        }
        public double getHeight() {
            return height;
        }
    }
    

    ターゲットActivity受信オブジェクト

    import...
    import java.io.Serializable;
    
    Intent intent=getIntent();
    Person person=
          (Person)intent.getSerializableExtra("Lishaoyin");
    

     ここでは、getSerializableExtra()メソッドを使用して、伝達されたオブジェクトを取得します.
    public Serializable getSerializableExtra(String name)
    

     その戻り値はSerializableタイプなので、そのオブジェクトを使用するには、強制タイプ変換を行う必要があります.

    Activityターゲット側コードの完全な切り替え

    import...
    import java.io.Serializable;
    
    public class TargetActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //load targetActivity.xml
            setContentView(R.layout.targetActivity);
            
            Intent intent=getIntent();
            Person person=
                  (Person)intent.getSerializableExtra("Lishaoyin");
            
            Toast.makeText(this,person.getName(),LENGTH_SHORT).show();
        }
    }
    

    Parcelable


    概要


    ParcelableインタフェースはParcelable.javaに定義され、Androidがオブジェクトを渡すためのインタフェースである.Serializableインタフェースと同様に、被伝達オブジェクトが他のクラスのオブジェクトを参照する場合、被引用オブジェクトのクラスもParcelableインタフェースを実現しなければならない.

    実装手順


    1.実現describeContents()方法、一般的に直接return 0でよい.
    @Override
    public int describeContents() {
        return 0;  //directly return 0 generally
    }
    

    2.伝達されたオブジェクトで使用されるすべてのフィールドをParcelコンテナに書き込むことによって、オブジェクトデータをシーケンス化し、必要でない場合は書き込まなくてもよいwriteToParcel()メソッドを実装する.
    public void writeToParcel(Parcel dest,int flags) {
        dest.writeString(name);
        dest.writeDouble(height);
        dest.writeInt(weight);
    }
    

     この方法ではwriteXXX()を用いて基本データ型およびString型をParcelコンテナに書き込むが,直接シーケンス化boolean型の方法,すなわちwriteBoolean()は存在しないことに注意すべきである.booleanタイプを使用する必要がある場合は、他の方法で間接的に実装します.3.Creator>のインスタンスCREATORを作成し、その2つの方法を書き換える.
    public static final Creator<?> CREATOR=new Creator<Person>() {
    
        @Override
        public Person createFromParcel(Parcel source) {
            Person person=new Person();
            person.name=source.readString();
            person.height=source.readDouble();
            person.weight=source.readInt();
            return person;
        }
        
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };  //don't forget ";"
    

    Creator>は汎用インタフェースであり、>は自動適合タイプパラメータを表し、上記の例でCREATORインスタンスを作成すると自動的に適合Personクラスに適合する. 書き換えcreateFromParcel()では、readXXX()メソッドを使用してオブジェクトデータを逆シーケンス化します.特に注意:逆シーケンス化順序はシーケンス化順序と一致しなければなりません.そうしないと、データが錯乱します.例えば、先にnameをシーケンス化し、さらにheightをシーケンス化し、最後にweightをシーケンス化すると、逆シーケンス化も先にnameを逆シーケンス化し、再び逆シーケンス化heightを逆シーケンス化し、最後に逆シーケンス化weightを逆シーケンス化しなければならない. 書き換えnewArray()メソッドでは、一般にnew Person[size]を直接返すとよい.4.putExtra()メソッドを使用してオブジェクトを渡し、ターゲットActivityを開きます.
    Person person=new Person();
    person.setPerson("Tony Stark",1.78,70);
    Intent intent=new Intent();
    intent.setClass(this,TargetActivity.class);
    intent.putExtra("Tony",person);
    startActivity(intent);
    

     この時点で使用されるputExtra()のバージョンは、次のとおりです.
    public Intent putExtra(String name,Parcelable value)
    

    まとめ


     実装Parcelableインタフェース方式の伝達対象は複雑で分かりにくいように見えるが、実際にはこのプロセスをテンプレートと見なすことができ、Android Studioは自動的に最も重要なコードを生成し、残りのカスタム部分は自由に発揮すればよい.

    完全なActivity切替イニシエータコード

    Person.java
    import...
    
    public class Person implements Parcelable {
        private String name;
        private double height;
        private int weight;
        public void setPerson(String name,double height,int weight) {
            this.name=name;
            this.height=height;
            this.weight=weight;
        }
        public String getName() {
            return name;
        }
        public double getHeight() {
            return height;
        }
        public int getWeight() {
            return weight;
        }
        
        @Override
        public int describeContents() {
            return 0;
        }
        @Override
        public void writeToParcel(Parcel dest,int flags) {
            dest.writeString(name);
            dest.writeDouble(height);
            dest.writeInt(weight);
        }
        
        public static final Creator<?> CREATOR=new Creator<Person>() {
        
            @Override
            public Person createFromParcel(Parcel source) {
                Person person=new Person();
                person.name=source.readString();
                person.height=source.readDouble();
                person.weight=source.readInt();
                return person;
            }
            @Override
            public Person[] newArray(int size) {
                return new Person[size];
            }        
        };  //don't forget ";"
    }
    
    CurrentActivity.java
    import...
    
    public class CurrentActivity extends Activity
                              implements View.OnClickListener {
                              
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //load currentActivity.xml
            setContentView(R.layout.currentActivity);
            Button btn_1=(Button)findviewById(R.id.btn_1);
            btn_1.setOnClickListener(this);
        }
        @Override
        public void onClick(View v) {
            Person person=new Person();
            person.setPerson("Tony Stark",1.78,70);
            
            Intent intent=Intent(this,TargetActivity.class);
            intent.putExtra("Tony",person);
            startActivity(intent);
        }                      
    }                          
    

    Activityターゲット受信オブジェクトの切り替え

    Intent intent=getIntent();
    Person person=(Person)intent.getParcelableExtra("Tony");
    

    getParcelableExtra()メソッドを使用して、強制タイプ変換に注意します.

    完全なActivity切替え先方コード

    TargetActivity.java
    import...
    
    public class TargetActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //load targetActivity.xml
            setContentView(R.layout.targetActivity);
            
            TextView tv_1=(TextView)findviewById(R.id.tv_1);
            TextView tv_2=(TextView)findviewById(R.id.tv_2);
            TextView tv_3=(TextView)findviewById(R.id.tv_3);
            
            Intent intent=getIntent();
            Person person=(Person)intent.getParcelableExtra("Tony");
            
            tv_1.setText(" :"+person.getName());
            tv_2.setText(" :"+person.getHeight());
            tv_3.setText(" :"+person.getWeight());
        }
    }
    

    SerializableとParcelableの簡単な比較


    同じ点


     両方ともシーケンス化と逆シーケンス化の操作がある.

    異なる点


    1.記憶媒体:Serializableオブジェクトをバイナリファイルに変換し、IO読み書きで外部記憶装置に記憶する.Parcelableオブジェクトをメモリに格納し、直接メモリにデータの読み書きを行います.2.読み書き速度:Parcelableメモリ上で直接データの読み書きを行うため、Parcelableの読み書き速度はより速い.3.記憶保持:Serializableオブジェクトを外部機器に記憶するため、Serializableを使用してオブジェクトの現在の状態を永続的に保存することができる.Parcelableオブジェクトをメモリに格納するため、プログラムを再起動するたびにオブジェクトのステータスが失われます.3.用途:Serializableオブジェクトをバイナリファイルに変換するので、プロセス間でオブジェクトを転送したり、プログラムを外部記憶装置に転送したり、プログラムをネットワークに転送したりすることができます.Parcelableオブジェクトの状態を永続的に保存する必要のない伝達オブジェクトの場合に使用します.

    まとめ


     一般的に、Activity間でオブジェクトを渡すには、オブジェクトの状態を永続的に保存する必要はないので、性能を考慮してParcelableを優先的に使用します.
    比較タイプ
    Serializable
    Parcelable
    ストレージメディア
    がいぶきおくそうち
    メモリ
    読み書き速度
    一般
    より速い
    きおくほじ
    永続的なストレージ
    一時記憶
    ご叱正を歓迎します