Android: Parcelable和Serializable的区别?

为什么Android为序列化对象提供了两个接口?可序列化对象与Android Binder和AIDL文件互选吗?

238343 次浏览

可序列化的是一个标准的Java接口。您只需通过实现接口将类标记为Serializable, Java将在某些情况下自动序列化它。

Parcelable是一个Android特定的接口,你可以自己实现序列化。创建它的目的是要比Serializable高效得多,并解决默认Java序列化方案的一些问题。

我相信Binder和AIDL可以用于可打包对象。

但是,你可以在intent中使用Serializable对象。

你可以在intent中使用serializable对象,但是在使serialize成为Parcelable对象时,它会给出一个严重的异常,如NotSerializableException。不建议使用serializable和Parcelable。所以最好是扩展Parcelable与你想要使用的对象捆绑和意图。由于这个Parcelable是android特定的,所以它没有任何副作用。 :) < / p >

如果你想成为一个好公民,花额外的时间去实施 可打包,因为它的运行速度快10倍,使用更少 资源。< / p > 然而,在大多数情况下,Serializable的速度并不慢 明显。您可以随意使用它,但请记住序列化是 这是一个昂贵的操作,所以请将其保持在最小值

如果你试图传递一个包含数千个序列化对象的列表, 整个过程可能会超过一秒钟。它 能不能使过渡或旋转从纵向到横向感觉很 缓慢。< / p >

源到此点:http://www.developerphil.com/parcelable-vs-serializable/

在Android中,我们不能只是将对象传递给活动。要做到这一点,对象必须实现SerializableParcelable接口。

可序列化的

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;
}


// return age
public int 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");

你可以传递Parcelable对象的ArrayList,如下:

// 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");

结论

  1. Parcelable接口比Serializable接口快
  2. Serializable接口相比,Parcelable接口的实现需要更多的时间
  3. Serializable接口更容易实现
  4. Serializable接口创建了大量的临时对象,并导致相当多的垃圾收集
  5. Parcelable数组可以通过Intent在android中传递

打包比使用Binder序列化快得多,因为序列化使用反射并导致许多GC。Parcelable是为了优化传递对象而设计的。

这是参考链接。 http://www.developerphil.com/parcelable-vs-serializable/ < / p >

我将成为一个支持Serializable的人。由于这些设备比几年前好得多,速度上的差异已经不那么明显了,而且还有其他更微妙的差异。有关更多信息,请参阅我的博客的帖子。

1. 可序列化的

< p > @see http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html < / p >

什么接口?

  • 是标准的Java接口吗

速度

  • 比Parcelable慢

2. Parcelable

< p > @see http://developer.android.com/reference/android/os/Parcelable.html < / p >

什么接口?

    <李>是android。操作系统接口
    • 这意味着谷歌开发的Parcelable在android上有更好的性能
    • 李< / ul > < / >

    速度

    • 更快(因为它针对android开发进行了优化)

    综上所述

    要知道Serializable是一个标准的Java接口,Parcelable是Android开发的接口

在编组和解组方面存在一些性能问题。Parcelable比Serializable快两倍。

请浏览以下连结:

http://www.3pillarglobal.com/insights/parcelable-vs-java-serialization-in-android-app-development

如果你在android studio中使用paracelable插件,parcelable的实现可以更快。搜索Android Parcelable代码生成器

在Parcelable中,开发人员编写用于编组和反编组的自定义代码,因此与Serialization相比,它创建的垃圾对象更少。由于这个自定义实现,Parcelable over Serialization的性能显著提高(大约快两倍)。

Serializable是一个标记接口,这意味着用户不能根据自己的需求编组数据。在序列化中,使用Java反射API在Java虚拟机(JVM)上执行编组操作。这有助于识别Java对象的成员和行为,但最终也会创建大量垃圾对象。因此,与Parcelable相比,Serialization进程较慢。

编组和反编组的含义是什么?

简单地说,“marshalling”;指将数据或对象转换为字节流的过程。是将字节流转换回原始数据或对象的反向过程。转换是通过“序列化”实现的。

http://www.jguru.com/faq/view.jsp?EID=560072

Serializable接口可以像Parcelable接口一样使用,从而获得(不是很多)更好的性能。 只需覆盖这两个方法来处理手动编组和解组过程:

private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException

不过,在我看来,在开发原生Android时,使用Android api是正确的选择。

看到的:

Parcelable是Android开发中的一种标准。但不是因为速度

Parcelable是数据传输的推荐方法。但如果你正确使用serializable,如这种回购所示,你会发现serializable有时甚至比parcelable更快。或者至少时间是可以比较的。

Parcelable比Serializable快吗?

不,如果序列化操作正确的话。

一般Android设备上的Java序列化(如果操作得当*)在写方面比Parcelable快3.6倍,在读方面快1.6倍。它还证明了Java序列化(如果使用得当)是一种快速的存储机制,即使在11000个对象(每个对象有10个字段)的相对较大的对象图中也能给出可接受的结果。

*旁注是,通常每个盲目地说“Parcelable要快得多”的人。将其与默认的自动序列化进行比较,后者在内部使用了大量反射。这是不公平的比较,因为Parcelable使用手动(非常复杂的)过程将数据写入流。通常没有提到的是,根据文档,标准Java Serializable也可以通过手动方式实现,使用writeObject()和readObject()方法。有关更多信息,请参阅JavaDocs。为了获得最佳性能,应该这样做。

所以,如果serializable更快更容易实现,为什么android有parcelable呢?

原因在于本地代码。创建Parcelable不仅仅是为了进程间通信。它也可以用于intercode沟通。你可以从c++原生层发送和接收对象。就是这样。

你应该选择什么?两者都很有效。但我认为Parcelable是更好的选择,因为谷歌推荐它,你可以从这个帖子中看到,它更受欢迎。

可序列化的

Serializable是一个可标记的接口,也可以作为空接口调用。它没有任何预先实现的方法。Serializable将对象转换为字节流。因此用户可以在一个活动之间传递数据到另一个活动。可序列化的主要优点是创建和传递数据非常容易,但与可打包相比,它是一个缓慢的过程。

Parcelable

可打包的比可序列化的快。Parcel able将对象转换为字节流,并在两个活动之间传递数据。与序列化相比,编写可包的代码有点复杂。在两个活动之间传递数据时,它不会创建更多的临时对象。

我的回答有点晚了,但我希望它能帮助到其他人。

根据速度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
}


}

1. 可序列化的

接口是一个标记(没有抽象方法的接口),不需要重新定义任何东西。

2. Parcelable

具有抽象方法的接口。在实现它的时候,你需要重新定义所有的抽象方法,指定哪些字段以及你需要写/读的顺序(通常工作室自己可以生成它们)。

enter image description here

实际上没有人用Kotlin编写。对此有一个特殊的注释,由于它,这个接口的实现将自动生成。要使用它,你需要添加一个特殊的插件。

  • 在构建。在插件部分,添加另一个插件:id“kotlin-parcelize”

enter image description here

  • 同步项目

你不必担心实现方法,你所需要的只是实现Parcelable接口并添加@Parcelize注释。

enter image description here

一切都会好的,工作很快!

结果

如果实现Parcelable接口而不是Serializable接口,实现过程会更快。

Parcelable将对象转换为字节流,以便在Android的进程之间传递对象。

序列化将POJO转换为字符串(JSON字符串),并用于跨平台传输对象信息。