Android:Parcelable 和 Serializable 之间的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3323074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:43:12  来源:igfitidea点击:

Android: Difference between Parcelable and Serializable?

androidparcelableserializable

提问by live2dream95

Why does Android provide 2 interfaces for serializing objects? Do Serializable objects interopt with Android Binderand AIDL files?

为什么 Android 提供了 2 个用于序列化对象的接口?Serializable 对象是否与 AndroidBinder和 AIDL 文件互操作?

回答by Sujith

In Android we cannot just pass objects to activities. To do this the objects must either implement Serializableor Parcelableinterface.

在 Android 中,我们不能仅仅将对象传递给活动。为此,对象必须实现SerializableParcelable接口。

Serializable

可序列化

Serializableis a standard Java interface. You can just implement Serializableinterface and add override methods. The problem with this approach is that reflection is used and it is a slow process. This method creates a lot of temporary objects and causes quite a bit of garbage collection. However, Serializableinterface is easier to implement.

Serializable是一个标准的Java接口。您可以只实现Serializable接口并添加覆盖方法。这种方法的问题在于使用了反射,而且这是一个缓慢的过程。此方法会创建大量临时对象并导致相当多的垃圾收集。但是,Serializable接口更容易实现。

Look at the example below (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

可包裹

Parcelableprocess is much faster than Serializable. One of the reasons for this is that we are being explicit about the serialization process instead of using reflection to infer it. It also stands to reason that the code has been heavily optimized for this purpose.

Parcelable过程比Serializable. 造成这种情况的原因之一是我们明确说明了序列化过程,而不是使用反射来推断它。代码已经为此目的进行了大量优化也是理所当然的。

Look at the example below (Parcelable):

看下面的例子(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");

You can pass ArrayListof Parcelable objects as below:

您可以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");

Conclusion

结论

  1. Parcelableis faster than Serializableinterface
  2. Parcelableinterface takes more time to implement compared to Serializableinterface
  3. Serializableinterface is easier to implement
  4. Serializableinterface creates a lot of temporary objects and causes quite a bit of garbage collection
  5. Parcelablearray can be passed via Intent in android
  1. ParcelableSerializable接口快
  2. ParcelableSerializable接口相比,接口需要更多的时间来实现
  3. Serializable接口更容易实现
  4. Serializable接口创建了很多临时对象并导致相当多的垃圾收集
  5. Parcelable数组可以通过android中的Intent传递

回答by Cheryl Simon

Serializableis a standard Java interface. You simply mark a class Serializable by implementing the interface, and Java will automatically serialize it in certain situations.

Serializable是一个标准的 Java 接口。您只需通过实现接口来标记一个类 Serializable,Java 会在某些情况下自动对其进行序列化。

Parcelableis an Android specific interface where you implement the serialization yourself. It was created to be far more efficient that Serializable, and to get around some problems with the default Java serialization scheme.

Parcelable是一个 Android 特定的接口,您可以在其中自己实现序列化。它的创建是为了比 Serializable 更高效,并解决默认 Java 序列化方案的一些问题。

I believe that Binder and AIDL work with Parcelable objects.

我相信 Binder 和 AIDL 可以处理 Parcelable 对象。

However, you can use Serializable objects in Intents.

但是,您可以在 Intent 中使用 Serializable 对象。

回答by Farhana

Parcelablevs SerializableI refer these two.

Parcelablevs Serializable我指的是这两个。

For Java and Kotlin

对于 Java 和 Kotlin

1) Java

1) 爪哇

Serializable, the Simplicity

可序列化,简单

What is Serializable?

Serializable is a standard Java interface. It is not a part of the Android SDK. Its simplicity is its beauty. Just by implementing this interface your POJO will be ready to jump from one Activity to another.

什么是可序列化?

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;
}
}
  • The beauty of serializable is that you only need to implement the Serializable interface on a class and its children. It is a marker interface, meaning that there is no method to implement, Java will simply do its best effort to serialize it efficiently.

  • The problem with this approach is that reflection is used and it is a slow process. This mechanism also tends to create a lot of temporary objects and cause quite a bit of garbage collection.

  • 可序列化的美妙之处在于您只需要在类及其子类上实现 Serializable 接口。它是一个标记接口,意味着没有方法可以实现,Java 将尽最大努力有效地序列化它。

  • 这种方法的问题在于使用了反射,而且这是一个缓慢的过程。这种机制还倾向于创建大量临时对象并导致相当多的垃圾收集。

Parcelable, The Speed

Parcelable,速度

What is Parcelable?

Parcelable is another interface. Despite its rival (Serializable in case you forgot), it is a part of the Android SDK. Now, Parcelable was specifically designed in such a way that there is no reflection when using it. That is because we are being really explicit for the serialization process.

什么是可包裹?

Parcelable 是另一个接口。尽管它是竞争对手(如果您忘记了可序列化),它仍然是 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];
    }
};
}

Now, The winner is

现在,赢家是

enter image description here

在此处输入图片说明

The results of the tests conducted by Philippe Breault show that Parcelable is more than 10x faster than Serializable. Some other Google engineers stand behind this statement as well.

Philippe Breault 进行的测试结果表明 Parcelable 比 Serializable 快 10 倍以上。其他一些 Google 工程师也支持这一声明。

According to them, the default Serializable approach is slower than Parcelable. And here we have an agreement between the two parties! BUT, it is unfair to compare these two at all! Because with Parcelable we are actually writing custom code. Code specifically created for that one POJO. Thus, no garbage is created and the results are better. But with the default Serializable approach, we rely on the automatic serialization process of Java. The process is apparently not custom at all and creates lots of garbage! Thus, the worse results.

根据他们的说法,默认的 Serializable 方法比 Parcelable 慢。在这里,我们有两方之间的协议!但是,比较这两者是不公平的!因为使用 Parcelable 我们实际上是在编写自定义代码。专门为那个 POJO 创建的代码。因此,不会产生垃圾并且结果更好。但是使用默认的 Serializable 方法,我们依赖于 Java 的自动序列化过程。该过程显然根本不是自定义的,并且会产生大量垃圾!因此,结果更糟。

Stop Stop!!!!, Before making decision

停止停止!!!,在做决定之前

Now, there is another approach. The whole automatic process behind Serializable can be replaced by custom code which uses writeObject() & readObject() methods. These methods are specific. If we want to rely on the Serializable approach in combination with custom serialization behavior, then we must include these two methods with the same exact signature as the one below:

现在,还有另一种方法。Serializable 背后的整个自动过程可以由使用 writeObject() 和 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;

And now a comparison between Parcelable and custom Serializable seems fair! The results may be surprising! The custom Serializable approach is more than 3x faster for writes and 1.6x faster for reads than Parcelable.

现在将 Parcelable 和自定义 Serializable 进行比较似乎很公平!结果可能出人意料!与 Parcelable 相比,自定义 Serializable 方法的写入速度快 3 倍以上,读取速度快 1.6 倍。

Edited:-----

编辑:-----

2) Kotlinx Serialization

2) Kotlinx 序列化

Kotlinx SerializationLibrary

Kotlinx序列化

For Kotlin serialization need to add below dependency and plugin

implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1"

apply plugin: 'kotlinx-serialization'

Your build.gradlefile

你的build.gradle档案

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlinx-serialization'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.smile.kotlinxretrosample"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Serializingis done quite easily, you need to annotate the intended class with the @Serializableannotation as below

序列化很容易完成,您需要使用注释对预期的类进行@Serializable注释,如下所示

import kotlinx.serialization.Serializable
@Serializable
class Field {
    var count: Int = 0
    var name: String = ""
}

Two more annotations to note are transientand optional. Using transient will have the serializer ignore that field and using optional will allow the serializer not to break if a field is missing, but at the same time a default value will need to be provided.

需要注意的另外两个注释是transientoptional。使用瞬态将使序列化器忽略该字段,使用可选将允许序列化器在缺少字段时不会中断,但同时需要提供默认值。

@Optional
var isOptional: Boolean = false
@Transient
var isTransient: Boolean = false

Note: This can as well work with data classes.

注意:这也适用于数据类。

Now to actually use this in action let's take an example of how to convert a JSON to object and back

现在要实际使用它,让我们举一个例子来说明如何将 JSON 转换为对象并返回

 fun toObject(stringValue: String): Field {
        return JSON.parse(Field.serializer(), stringValue)
    }

    fun toJson(field: Field): String {
        //Notice we call a serializer method which is autogenerated from our class 
        //once we have added the annotation to it
        return JSON.stringify(Field.serializer(), field)
    }

For more

对于更多

回答by codercat

If you want to be a good citizen, take the extra time to implement Parcelable since it will perform 10 times faster and use less resources.

However, in most cases, the slowness of Serializable won't be noticeable. Feel free to use it but remember that serialization is an expensive operation so keep it to a minimum.

If you are trying to pass a list with thousands of serialized objects, it is possible that the whole process will take more than a second. It can make transitions or rotation from portrait to lanscape feel very sluggish.

如果你想成为一个好公民,请花额外的时间来实现 Parcelable,因为它的执行速度会快 10 倍,并且使用的资源更少。

但是,在大多数情况下,Serializable 的缓慢不会很明显。随意使用它,但请记住,序列化是一项昂贵的操作,因此请尽量减少它。

如果您尝试传递包含数千个序列化对象的列表,则整个过程可能需要一秒钟以上。它可以使从纵向到横向的过渡或旋转感觉非常缓慢。

Source to this point: http://www.developerphil.com/parcelable-vs-serializable/

来源:http: //www.developerphil.com/parcelable-vs-serializable/

回答by Uts

In Parcelable, developers write custom code for marshaling and unmarshaling so it creates less garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves (around two times faster), because of this custom implementation.

在 Parcelable 中,开发人员为编组和解组编写自定义代码,因此与序列化相比,它创建的垃圾对象更少。由于这种自定义实现,Parcelable 相对于序列化的性能显着提高(大约快两倍)。

Serializable is a marker interface, which implies that user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java object's member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.

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

Edit: What is the meaning of marshalling and unmarshalling?

编辑:编组和解组是什么意思?

In few words, "marshalling" refers to the process of converting the data or the objects inbto a byte-stream, and "unmarshalling" is the reverse process of converting the byte-stream beack to their original data or object. The conversion is achieved through "serialization".

简而言之,“编组”是指将数据或对象转换为字节流的过程,而“解组”是将字节流转换为原始数据或对象的逆过程。转换是通过“序列化”实现的。

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

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

回答by Nemanja Kovacevic

I'm actually going to be the one guy advocating for the Serializable. The speed difference is not so drastic any more since the devices are far better than several years ago and also there are other, more subtle differences. See my blogpost on the issue for more info.

我实际上将成为提倡可序列化的人。速度差异不再那么明显,因为这些设备比几年前要好得多,而且还有其他更细微的差异。有关更多信息,请参阅关于该问题的博客文章。

回答by Maksim Turaev

Parcelable is sort of a standard in Android development. But not because of speed

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

Parcelable is recommended approach for data transfers. But if you use serializable correctly as shown in this repo, you will see that serializable is sometimes even faster then parcelable. Or at least timings are comparable.

Parcelable 是推荐的数据传输方法。但是,如果您如本 repo 中所示正确使用可序列化,您会发现可序列化有时甚至比 Parcelable 更快。或者至少时间是可比的。

Is Parcelable faster then Serializable?

Parcelable 比 Serializable 快吗?

Usual Java serialization on an average Android device (if done right *) is about 3.6 times faster than Parcelable for writes and about 1.6 times faster for reads. Also it proves that Java Serialization (if done right) is fast storage mechanism that gives acceptable results even with relatively large object graphs of 11000 objects with 10 fields each.

* The sidenote is that usually everybody who blindly states that "Parcelable is mush faster" compares it to default automatic serialization, which uses much reflection inside. This is unfair comparison, because Parcelable uses manual (and very complicated) procedure of writing data to the stream. What is usually not mentioned is that standard Java Serializable according to the docs can also be done in a manual way, using writeObject() and readObject() methods. For more info see JavaDocs. This is how it should be done for the best performance.

普通 Android 设备上通常的 Java 序列化(如果做得正确*)比 Parcelable 的写入快约 3.6 倍,读取快约 1.6 倍。它还证明了 Java 序列化(如果做得好)是一种快速存储机制,即使在具有 11000 个对象且每个对象有 10 个字段的相对较大的对象图的情况下,也能提供可接受的结果。

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

So, if serializable is faster and easier to implement, why android has parcelable at all?

那么,如果可序列化更快更容易实现,为什么 android 有parcelable呢?

The reason is native code. Parcelable is created not just for interprocess communication. It also can be used for intercode communication. You can send and recieve objects from C++ native layer. That's it.

原因是本机代码。Parcelable 不仅用于进程间通信。也可用于码间通信。您可以从 C++ 本机层发送和接收对象。就是这样。

What should you choose? Both will work good. But I think that Parcelable is better choice since it is recommended by google and as you can see from this thread is much more appreciated.

你应该选择什么?两者都会很好地工作。但我认为 Parcelable 是更好的选择,因为它是由 google 推荐的,正如您从该线程中看到的那样,它更受欢迎。

回答by kenju

1. Serializable

1. 可序列化

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

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

Interface of what?

什么接口?

  • is a standard Java interface
  • 是一个标准的Java接口

Speed

速度

  • slower than Parcelable
  • 比 Parcelable 慢

2. Parcelable

2. 可包裹

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

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

Interface of what?

什么接口?

  • is android.os interface
    • which means Google developped Parcelable for better performance on android
  • 是android.os接口
    • 这意味着 Google 开发了 Parcelable 以在 android 上获得更好的性能

Speed

速度

  • faster ( because it is optimized for usage on android development)
  • 更快(因为它针对 android 开发的使用进行了优化)

> In Conclusion

> 结论

Be aware that Serializable is a standard Java interface, and Parcelable is for Android Development

注意Serializable是标准的Java接口,Parcelable是针对Android开发的

回答by Tushar Thakar

There is some performance issue regarding to marshaling and unmarshaling. Parcelable is twice faster than Serializable.

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

Please go through the following link:

请通过以下链接:

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

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

回答by Deep P

Implementation of parcelable can be faster if you use paracelable plugin in android studio. search for Android Parcelable code generator

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