Intent転送オブジェクト
44457 ワード
目次
Serializable
概要
ライトコードについては,Intentを用いてActivity間でオブジェクトを伝達するが,最も簡単な方法は被伝達オブジェクトのクラスにSerializable
空インタフェースを実現させることである. Serializable
Android定義のインタフェースではなく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
ストレージメディア
がいぶきおくそうち
メモリ
読み書き速度
一般
より速い
きおくほじ
永続的なストレージ
一時記憶
ご叱正を歓迎します
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;
}
}
Person person=new Person();
person.name="Lishaoyin";
person.height="1.70";
Intent intent=new Intent(this,TargetActivity.class);
intent.putExtra("Lishaoyin",person);
startActivity(intent);
public Intent putExtra(String name,Serializable value)
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
}
}
//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;
}
}
import...
import java.io.Serializable;
Intent intent=getIntent();
Person person=
(Person)intent.getSerializableExtra("Lishaoyin");
public Serializable getSerializableExtra(String name)
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.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());
}
}