なぜParcelableインタフェースを使用します。
シリアライズインターフェース等は、オブジェクトクラスは意図とバインダーを渡すことができる可能にするために、クラスとして直列化および直列化機能を実現しています。
ParcelableインタフェースとSerializableインタフェースの違い:
1.直列化インタフェースは、Javaのネイティブ配列で使用する単純なインターフェイスを提供するが、そのシリアライゼーションおよびデシリアライゼーションプロセスは、大きなオーバーヘッド、I / O操作の多くを必要とするからです。
2. ParcelableインターフェイスがインターフェイスのAndroidの配列によって提供され、Androidプラットフォーム上で使用するのに適している、Androidはまた、シリアル化をお勧めします。けれども使用するもう少し面倒ですが、それは、非常に効率的ですので、我々はParcelableを使用することを好みます。(ASの、実際には、今、それはまた、非常に便利ですので、自動的にインポートされます。)
ParcelableインタフェースとSerializableインタフェースの使用シナリオ:
1. Parcelable 主メモリのシリアル化のために使用されるような、我々が使用するときのように、または優先この方法で使用されるインテントバインダー転送オブジェクト。
2.シリアライズは、主にネットワークストレージデバイス上のオブジェクトをシリアル化するために使用されるか、またはオブジェクトを透過しました。
例Parcelableインタフェース:
// Girl.java 实现了 Parcelable 接口的类
package com.cfm.parcelableactivity;
public class Girl implements Parcelable {
private String mName;
private String mDream;
public Girl(String name, String dream) {
mName = name;
mDream = dream;
}
protected Girl(Parcel in) {
mName = in.readString();
mDream = in.readString();
}
public static final Creator<Girl> CREATOR = new Creator<Girl>() {
@Override
public Girl createFromParcel(Parcel in) {
return new Girl(in);
}
@Override
public Girl[] newArray(int size) {
return new Girl[size];
}
};
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getDream() {
return mDream;
}
public void setDream(String dream) {
mDream = dream;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mName);
dest.writeString(mDream);
}
}
// User.java 实现了 Parcelable 接口的类,并包含实现了 Parcelable 接口的类的对象
package com.cfm.parcelableactivity;
public class User implements Parcelable {
private int mId;
private String mName;
private String mDream;
private Girl mGirl;
public User(int id, String name, String dream, Girl girl) {
mId = id;
mName = name;
mDream = dream;
mGirl = girl;
}
/**
* 反序列化过程。从序列化后的对象中创建原始对象。
*/
private User(Parcel in) {
mId = in.readInt();
mName = in.readString();
mDream = in.readString();
mGirl = in.readParcelable(Thread.currentThread().getContextClassLoader());
}
public static final Creator<User> CREATOR = new Creator<User>() {
/**
* 从序列化的对象中创建原始对象。也就是反序列化过程。
*/
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
/**
* 创建指定长度的原始对象数组。
*/
@Override
public User[] newArray(int size) {
return new User[size];
}
};
public int getId() {
return mId;
}
public void setId(int id) {
mId = id;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getDream() {
return mDream;
}
public void setDream(String dream) {
mDream = dream;
}
public Girl getGirl() {
return mGirl;
}
/**
* 返回当前对象的内容描述。
* @return 如果含有文件描述符,返回1;否则返回0。几乎所有情况都返回0.
*/
@Override
public int describeContents() {
return 0;
}
/**
* 将当前对象写入序列化结构中,也就是序列化过程。
* @param flags 有两种值:0或1。为 1 时标识当前对象需要作为返回值返回,不能立即释放资源;几乎所有情况都返回0。
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mId);
dest.writeString(mName);
dest.writeString(mDream);
dest.writeParcelable(mGirl, 0);
}
}
// FirstActivity.java
package com.cfm.parcelableactivity;
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.first_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("cfmtest", new User(1, "cfm", "open source", new Girl("ym", "Become Better and Better")));
startActivity(intent);
}
});
}
}
// SecondActivity.java
package com.cfm.parcelableactivity;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
User user = getIntent().getParcelableExtra("cfmtest");
Log.d("cfmtest-SecondActivity", "mId: " + user.getId());
Log.d("cfmtest-SecondActivity", "mName: " + user.getName());
Log.d("cfmtest-SecondActivity", "mDream: " + user.getDream());
Log.d("cfmtest-SecondActivity", "mGirl.name: " + user.getGirl().getName());
Log.d("cfmtest-SecondActivity", "mGirl.dream: " + user.getGirl().getDream());
}
}
// output
cfmtest-SecondActivity: mId: 1
cfmtest-SecondActivity: mName: cfm
cfmtest-SecondActivity: mDream: open source
cfmtest-SecondActivity: mGirl.name: ym
cfmtest-SecondActivity: mGirl.dream: Become Better and Better
ここでの意図によってFirstActivityが達成されるParcelableユーザーインターフェイスがSecondActivityに伝達され、あなたはSecondActivityが正常に受信して、ユーザーオブジェクトの属性を印刷見ることができます。
これは、シリアル化を通して見ることができ、デシリアライズプロセスParcelableインタフェースは、主に3つのステップをオブジェクト:
1.プロセスシーケンス
(、のIntフラグパーセルDEST)wirteToParcelによって実行される方法は、最終的に書き込み方法パーセルの一連によって達成します。(ASを使用して、それは私たちが自動的に生成し、このメソッドを実装するのに役立ちます。)
2.逆シリアル化のプロセス
CREATORによって行われ、オブジェクトと配列を作成すると、readメソッド小包の一連のデシリアライゼーション・プロセスを完了するために、どのように、その内部配列をマーク。
3.説明
describeContentsによって行わ()メソッドは、ファイル記述子が存在する場合にのみ、現在のオブジェクト、1を返し、ほとんどすべての残りの0戻ります。
注:私たちは、女の子が他のシリアライズ可能なオブジェクトであるため、オブジェクトなので、それは現在のスレッドの直列化復元のコンテキストクラスローダの間に渡す必要があり、逆シリアル化メソッドユーザー(パーセル)を呼び出します。
mGirl =in.readParcelable(Thread.currentThread().getContextClassLoader());