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


当前回答

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

请浏览以下连结:

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

其他回答

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

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

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

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

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

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.

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

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

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

结论

Parcelable接口比Serializable接口快 与可串行化接口相比,可打包接口需要更多的时间来实现 可序列化的接口更容易实现 可序列化接口创建了大量临时对象,并导致大量垃圾收集 Parcelable数组可以通过Intent在android中传递

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

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

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

看到的:

https://bitbucket.org/afrishman/androidserializationtest/ https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

可序列化的

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

Parcelable

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