381

为什么Android提供2个接口来序列化对象?可序列化对象是否与 AndroidBinder和 AIDL 文件互操作?

4

14 回答 14

534

在 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过程比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");

您可以传递ArrayListParcelable 对象,如下所示:

// 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. ParcelableSerializable界面快
  2. Parcelable与接口相比,接口需要更多时间来Serializable实现
  3. Serializable接口更容易实现
  4. Serializable接口创建了很多临时对象并导致相当多的垃圾收集
  5. Parcelable数组可以通过 android 中的 Intent 传递
于 2014-05-14T06:46:54.053 回答
210

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

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

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

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

于 2010-07-24T02:21:24.420 回答
42

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

但是,在大多数情况下,Serializable 的缓慢性并不明显。随意使用它,但请记住,序列化是一项昂贵的操作,因此请将其保持在最低限度。

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

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

于 2014-03-12T11:44:35.350 回答
40

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

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

编辑:编组和解组的含义是什么?

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

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

于 2017-02-01T06:26:56.097 回答
29

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

Parcelable 是推荐的数据传输方法。但是如果你正确使用 serializable 如这个 repo所示,你会发现 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 的创建不仅仅是为了进程间通信。它也可用于代码间通信。您可以从 C++ 本机层发送和接收对象。而已。

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

于 2018-12-12T07:06:27.603 回答
21

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

于 2015-03-25T02:12:16.847 回答
12

1.可序列化

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

什么接口?

  • 是一个标准的Java接口

速度

  • 比 Parcelable 慢

2. 可打包

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

什么接口?

  • 是android.os界面
    • 这意味着谷歌开发了 Parcelable 以在 android 上获得更好的性能

速度

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

> 结论

请注意,Serializable 是标准的 Java 接口,而 Parcelable 是用于 Android 开发的

于 2015-08-18T08:37:57.700 回答
7

有一些关于编组和解组的性能问题。Parcelable 比 Serializable 快两倍。

请通过以下链接:

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

于 2015-12-31T08:01:28.007 回答
4

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

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

尽管如此,在我看来,在开发原生 Android 时,使用 Android api 是要走的路。

看 :

于 2017-04-24T08:03:21.710 回答
4

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

于 2016-08-22T04:25:58.973 回答
1

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

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

于 2014-07-15T15:14:57.400 回答
1

您可以在意图中使用可序列化对象,但在序列化 Parcelable 对象时,它可能会出现严重的异常,例如 NotSerializableException。是否不建议将 Serializable 与 Parcelable 一起使用。因此,最好使用要与捆绑和意图一起使用的对象来扩展 Parcelable。由于这个 Parcelable 是 android 特定的,所以它没有任何副作用。:)

于 2012-04-16T07:32:18.317 回答
1

我回答迟了,但希望能对其他人有所帮助。

速度方面,Parcelable > Serializable. 但是,Custom 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
    }

}
于 2019-11-15T10:44:08.780 回答
0

可序列化

Serializable 是一个可标记的接口,或者我们可以调用一个空接口。它没有任何预先实现的方法。Serializable 将对象转换为字节流。因此,用户可以将一个活动之间的数据传递给另一个活动。serializable 的主要优点是创建和传递数据非常容易,但与 parcelable 相比,这是一个缓慢的过程。

可包裹

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

于 2019-09-09T04:15:15.347 回答