答案 0 :(得分:390)
在Android中,我们不能只将对象传递给活动。为此,对象必须实现Serializable
或Parcelable
接口。
<强>序列化强>
Serializable
是标准的Java接口。您只需实现Serializable
接口并添加覆盖方法即可。这种方法的问题在于使用反射并且这是一个缓慢的过程。此方法会创建大量临时对象,并导致相当多的垃圾回收。但是,Serializable
界面更容易实现。
请看下面的示例(Serializable):
// MyObjects Serializable class
import java.io.Serializable;
import java.util.ArrayList;
import java.util.TreeMap;
import android.os.Parcel;
import android.os.Parcelable;
public class MyObjects implements Serializable {
private String name;
private int age;
public ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
public ArrayList<String> getAddress() {
if (!(address == null))
return address;
else
return new ArrayList<String>();
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");
// Passing MyObjects instance via intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getSerializableExtra("UniqueKey");
<强> Parcelable 强>
Parcelable
进程比Serializable
快得多。其中一个原因是我们明确了序列化过程而不是使用反射来推断它。它也有理由为此目的对代码进行了大量优化。
请看下面的示例(Parcelable):
// MyObjects Parcelable class
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
public class MyObjects implements Parcelable {
private int age;
private String name;
private ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
this.name = name;
this.age = age;
this.address = address;
}
public MyObjects(Parcel source) {
age = source.readInt();
name = source.readString();
address = source.createStringArrayList();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
dest.writeStringList(address);
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public ArrayList<String> getAddress() {
if (!(address == null))
return address;
else
return new ArrayList<String>();
}
public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
@Override
public MyObjects[] newArray(int size) {
return new MyObjects[size];
}
@Override
public MyObjects createFromParcel(Parcel source) {
return new MyObjects(source);
}
};
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");
// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getParcelableExtra("UniqueKey");
您可以传递ArrayList
Parcelable对象,如下所示:
// Array of MyObjects
ArrayList<MyObjects> mUsers;
// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putParcelableArrayListExtra("UniqueKey", mUsers);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayList("UniqueKey");
<强>结论强>
Parcelable
比Serializable
界面Parcelable
interface 相比,Serializable
接口需要更多时间来实现
Serializable
界面更易于实施Serializable
接口会创建大量临时对象并导致相当多的垃圾回收Parcelable
数组可以通过android中的Intent传递答案 1 :(得分:171)
答案 2 :(得分:36)
如果你想成为一个好公民,请花些额外的时间来实施 可分辨,因为它将执行速度提高10倍并且使用更少 资源。
但是,在大多数情况下,Serializable的速度不会很慢 显。随意使用它,但请记住序列化 这是一项昂贵的操作,所以要尽量减少。
如果您尝试传递包含数千个序列化对象的列表, 整个过程可能需要一秒钟以上。它 可以使从肖像到景观的过渡或旋转感觉非常 呆滞。
答案 3 :(得分:30)
Parcelable vs Serializable 我推荐这两个。
可序列化,简洁
什么是Serializable?
Serializable是标准的Java接口。它不是一部分 Android SDK。它的简洁是它的美丽。只是实现这一点 界面你的POJO将准备从一个Activity跳转到 另一个。
public class TestModel implements Serializable {
String name;
public TestModel(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
serializable的美妙之处在于您只需要在类及其子类上实现Serializable接口。它是一个标记接口,意味着没有方法可以实现,Java将尽最大努力有效地序列化它。
这种方法的问题在于使用反射并且这是一个缓慢的过程。这种机制也会产生大量的临时对象并导致相当多的垃圾收集。
Parcelable,The Speed
什么是Parcelable?
Parcelable是另一个界面。尽管它的竞争对手(Serializable in 如果您忘了),它是Android SDK的一部分。现在,Parcelable是 专门设计的方式是什么时候没有反射 使用它。那是因为我们真的很明白 序列化过程。
public class TestModel implements Parcelable {
String name;
public TestModel(String name, String id) {
this.name = name;
}
protected TestModel(Parcel in) {
this.name = in.readString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
}
public static final Parcelable.Creator<TestModel> CREATOR = new Parcelable.Creator<TestModel>() {
@Override
public TestModel createFromParcel(Parcel source) {
return new TestModel(source);
}
@Override
public TestModel[] newArray(int size) {
return new TestModel[size];
}
};
}
现在,获胜者是
Philippe Breault进行的测试结果表明,Parcelable比Serializable快10倍以上。其他一些Google工程师也支持这一陈述。
根据他们的说法,默认的Serializable方法比 Parcelable。在这里,我们双方达成协议! 但是,完全比较这两个是不公平的!因为有了Parcelable 我们实际上在编写自定义代码。代码专门为 那一个POJO。因此,不会产生垃圾,结果会更好。 但是使用默认的Serializable方法,我们依赖于自动化 Java的序列化过程。这个过程显然不是定制的 所有,并创造了大量的垃圾!因此,结果更糟。
停止!!!!,在作出决定之前
现在,还有另一种方法。 Serializable背后的整个自动过程可以用自定义代码替换,该代码使用writeObject()&amp; readObject()方法。这些方法是具体的。如果我们想依靠 与Serializable方法结合使用自定义序列化 行为,那么我们必须包含这两个方法完全相同 签名如下:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException;
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
现在Parcelable和自定义Serializable之间的比较看起来很公平!结果可能会令人惊讶!与Parcelable相比,自定义Serializable方法的写入速度提高了3倍,读取速度提高了1.6倍。
答案 4 :(得分:27)
在Parcelable中,开发人员编写用于编组和解组的自定义代码,因此与序列化相比,它创建的垃圾对象更少。由于这种自定义实现,Parcelable over Serialization的性能显着提高(大约快两倍)。
序列化是一种标记接口,这意味着用户无法根据需要封送数据。在序列化中,使用Java反射API在Java虚拟机(JVM)上执行编组操作。这有助于识别Java对象的成员和行为,但最终还是会创建大量垃圾对象。 由于这个原因,与Parcelable相比,序列化过程很慢。
编辑:编组和解组是什么意思?
简而言之,“编组”是指将数据或对象转换为字节流的过程,“解组”是将字节流beack转换为其原始数据或对象的相反过程。转换是通过“序列化”实现的。
答案 5 :(得分:16)
我实际上将成为一个倡导Serializable的人。速度差异不再那么激烈,因为这些设备比几年前要好得多,还有其他更微妙的差异。有关详细信息,请参阅此问题的my blog帖子。
答案 6 :(得分:11)
@see http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
@see http://developer.android.com/reference/android/os/Parcelable.html
请注意,Serializable是标准的Java接口,Parcelable是用于Android开发的
答案 7 :(得分:6)
关于编组和解编有一些性能问题。 Parcelable比Serializable快两倍。
请浏览以下链接:
http://www.3pillarglobal.com/insights/parcelable-vs-java-serialization-in-android-app-development
答案 8 :(得分:4)
如果你在android studio中使用paracelable插件,可以更快地实现parcelable。搜索Android Parcelable代码生成器
答案 9 :(得分:2)
建议使用Parcelable方法进行数据传输。但是,如果您正确使用this repo中所示的可序列化,则可以看到有时可序列化甚至比可打包更快。或者至少时间是可比的。
在一般的Android设备上,通常的Java序列化(如果操作正确*)比Parcelable的写入速度快约3.6倍,而读取的速度则快1.6倍。此外,它证明了Java序列化(如果操作正确)是一种快速存储机制,即使在相对较大的对象图(包含11000个对象,每个对象具有10个字段)的情况下,也能给出可接受的结果。
*旁注是,通常每个人盲目声明“ Parcelable的速度更快”,将其与默认的自动序列化进行比较,后者在内部使用了很多反射。这是不公平的比较,因为Parcelable使用手动(且非常复杂)的过程将数据写入流。通常没有提到的是,根据文档的标准Java Serializable也可以使用writeObject()和readObject()方法以手动方式完成。有关更多信息,请参见JavaDocs。这是应该这样做以获得最佳性能的方法。
原因是本机代码。创建Parcelable不仅用于进程间通信。它也可以用于代码间通信。您可以从C ++本机层发送和接收对象。就是这样。
您应该选择什么?两者都会很好地工作。但我认为,Parcelable是更好的选择,因为它是Google推荐的,并且从该线程可以看到,对此我们非常赞赏。
答案 10 :(得分:1)
您可以在意图中使用可序列化对象,但在序列化Parcelable对象时,它可能会产生严重的异常,如NotSerializableException。是否建议使用可序列化的Parcelable。因此,最好将Parcelable扩展为要与bundle和Intent一起使用的对象。因为这个Parcelable是特定于Android的,所以它没有任何副作用。 :)
答案 11 :(得分:1)
Serializable接口的使用方法与Parcelable接口的使用方式相同,可以获得更好的性能。 只需覆盖这两种方法来处理手动编组和解组过程:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
尽管如此,在我看来,在开发原生Android时,使用Android api是可行的方法。
见:
答案 12 :(得分:0)
Parced可以比使用Binder序列化快得多,因为可序列化使用反射并导致许多GC。 Parcelable设计优化传递对象。
这是参考链接。 http://www.developerphil.com/parcelable-vs-serializable/
答案 13 :(得分:0)
可序列化
Serializable是可标记的接口,或者我们可以将其称为空接口。它没有任何预先实现的方法。可序列化将把一个对象转换为字节流。因此,用户可以在一个活动到另一个活动之间传递数据。可序列化的主要优点是创建和传递数据非常容易,但是与可打包相比,这是一个缓慢的过程。
可包裹
具有包裹功能比可序列化速度更快。 Parcelable将把对象转换为字节流,并在两个活动之间传递数据。与序列化相比,编写可打包的代码有点复杂。在两个活动之间传递数据时,它不会创建更多临时对象。
答案 14 :(得分:0)
我的回答很晚,但是希望能对其他人有所帮助。
根据速度,Parcelable > Serializable
。但是,自定义可序列化是个例外。它几乎处于Parcelable范围内,甚至更快。
参考:https://www.geeksforgeeks.org/customized-serialization-and-deserialization-in-java/
示例:
要序列化的自定义类
class MySerialized implements Serializable {
String deviceAddress = "MyAndroid-04";
transient String token = "AABCDS"; // sensitive information which I do not want to serialize
private void writeObject(ObjectOutputStream oos) throws Exception {
oos.defaultWriteObject();
oos.writeObject("111111" + token); // Encrypted token to be serialized
}
private void readObject(ObjectInputStream ois) throws Exception {
ois.defaultReadObject();
token = ((String) ois.readObject()).subString(6); // Decrypting token
}
}