381

Android がオブジェクトをシリアル化するための 2 つのインターフェイスを提供するのはなぜですか? Serializable オブジェクトは Android および AIDLBinderファイルと相互接続しますか?

4

14 に答える 14

534

Android では、単にオブジェクトをアクティビティに渡すことはできません。これを行うには、オブジェクトが実装SerializableまたはParcelableインターフェースする必要があります。

シリアライズ可能

Serializable標準の Java インターフェイスです。インターフェイスを実装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。この理由の 1 つは、リフレクションを使用して推論するのではなく、シリアル化プロセスについて明示していることです。また、この目的のためにコードが大幅に最適化されていることも当然のことです。

以下の例を見てください (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");

結論

  1. ParcelableSerializableインターフェースより速い
  2. Parcelableインターフェイスに比べてSerializableインターフェイスの実装に時間がかかる
  3. Serializableインターフェイスの実装が容易
  4. Serializableインターフェイスは多くの一時オブジェクトを作成し、かなりの量のガベージ コレクションを引き起こします
  5. ParcelableAndroidではインテント経由で配列を渡すことができます
于 2014-05-14T06:46:54.053 に答える
210

Serializableは、標準の Java インターフェイスです。インターフェースを実装することによってクラス Serializable をマークするだけで、Java は特定の状況でそれを自動的にシリアライズします。

Parcelableは、シリアル化を自分で実装する Android 固有のインターフェイスです。これは、Serializable よりもはるかに効率的であり、デフォルトの Java シリアライゼーション スキームに関するいくつかの問題を回避するために作成されました。

Binder と AIDL は Parcelable オブジェクトで機能すると思います。

ただし、インテントで Serializable オブジェクトを使用できます。

于 2010-07-24T02:21:24.420 に答える
42

善良な市民になりたい場合は、Parcelable の実装に余分な時間を割いてください。実行速度が 10 倍速く、リソースの使用量が少ないからです。

ただし、ほとんどの場合、Serializable の遅さは目立ちません。自由に使用してください。ただし、シリアル化はコストのかかる操作であるため、最小限に抑えてください。

何千ものシリアル化されたオブジェクトを含むリストを渡そうとすると、プロセス全体に 1 秒以上かかる可能性があります。縦向きから横向きへの移行や回転が非常に遅く感じることがあります。

この時点までのソース: http://www.developerphil.com/parcelable-vs-serializable/

于 2014-03-12T11:44:35.350 に答える
29

Parcelable は、Android 開発の標準のようなものです。でも速さのせいじゃない

データ転送には Parcelable をお勧めします。ただし、この repoに示されているようにシリアライズ可能を正しく使用すると、シリアライズ可能がパーセル可能よりも高速な場合があることがわかります。または、少なくともタイミングは同等です。

Parcelable は Serializable よりも高速ですか?

いいえ、シリアル化が正しく行われていれば。

平均的な Android デバイスでの通常の Java シリアライゼーション (正しく行われた場合 *) は、Parcelable よりも書き込みで約 3.6 倍、読み取りで約 1.6 倍高速です。また、Java シリアライゼーションが (正しく行われた場合) 高速ストレージ メカニズムであり、それぞれ 10 フィールドを持つ 11000 オブジェクトの比較的大きなオブジェクト グラフでも許容できる結果が得られることも証明されています。

* 補足として、通常、「Parcelable の方がずっと速い」とやみくもに言う人は、内部で多くのリフレクションを使用するデフォルトの自動シリアル化と比較します。Parcelable はデータをストリームに書き込む手動の (そして非常に複雑な) 手順を使用するため、これは不公平な比較です。通常言及されていないのは、ドキュメントによると標準の Java Serializable は、 writeObject() および readObject() メソッドを使用して手動で行うこともできるということです。詳細については、JavaDocs を参照してください。これは、最高のパフォーマンスを得るために行うべき方法です。

それで、シリアライズ可能がより速く、より簡単に実装できるのなら、なぜアンドロイドはパーセル可能なのですか?

理由はネイティブコードです。Parcelable は、プロセス間通信のためだけに作成されたものではありません。また、コード間通信にも使用できます。C++ ネイティブ層からオブジェクトを送受信できます。それでおしまい。

あなたは何を選ぶべきですか?どちらもうまくいきます。しかし、Parcelable は Google によって推奨されているため、より良い選択だと思います。このスレッドからわかるように、はるかに高く評価されています。

于 2018-12-12T07:06:27.603 に答える
21

私は実際、Serializable を提唱する唯一の人物になるつもりです。デバイスは数年前よりもはるかに優れており、他にもより微妙な違いがあるため、速度の違いはそれほど劇的ではなくなりました. 詳細については、この問題に関する私のブログ投稿を参照してください。

于 2015-03-25T02:12:16.847 に答える
12

1.シリアライズ可能

@参照 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インターフェースです
    • これは、Google が Android でのパフォーマンスを向上させるために Parcelable を開発したことを意味します。

スピード

  • 高速 (Android 開発での使用に最適化されているため)

> おわりに

Serializable は標準の Java インターフェースであり、Parcelable は Android 開発用であることに注意してください。

于 2015-08-18T08:37:57.700 に答える
7

マーシャリングとアンマーシャリングに関するパフォーマンスの問題があります。Parcelable は Serializable よりも 2 倍高速です。

次のリンクを参照してください。

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

于 2015-12-31T08:01:28.007 に答える
4

android studio で paracelable プラグインを使用すると、parcelable の実装が高速になります。Android Parcelable コード ジェネレーターの検索

于 2016-08-22T04:25:58.973 に答える
1

インテントでシリアル化可能なオブジェクトを使用できますが、Parcelableオブジェクトをシリアル化するときに、NotSerializableExceptionのような重大な例外が発生する可能性があります。Parcelableでシリアライズ可能を使用することはお勧めしませんか。したがって、バンドルとインテントで使用するオブジェクトを使用してParcelableを拡張することをお勧めします。このParcelableはAndroid固有であるため、副作用はありません。:)

于 2012-04-16T07:32:18.317 に答える
1

シリアライズ可能はリフレクションを使用し、多くの GC を引き起こすため、Binder を使用したシリアライズ可能よりもパーセル可能の方がはるかに高速です。Parcelable は、オブジェクトを渡すために最適化する設計です。

参考リンクはこちら。 http://www.developerphil.com/parcelable-vs-serializable/

于 2014-07-15T15:14:57.400 に答える