Android: ความแตกต่างระหว่าง Parcelable และ Serializable


313

เหตุใด Android จึงมี 2 อินเตอร์เฟสสำหรับการทำให้เป็นอันดับวัตถุ? วัตถุที่ทำให้เป็นอนุกรมสามารถทำงานร่วมกับBinderไฟล์Android และ AIDL ได้หรือไม่?

คำตอบ:


444

ใน Android เราไม่สามารถส่งผ่านวัตถุไปยังกิจกรรมได้ เมื่อต้องการทำสิ่งนี้วัตถุต้องใช้งานSerializableหรือParcelableอินเทอร์เฟซ

serializable

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

    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

Parcelableกระบวนการเร็วกว่าSerializableมาก หนึ่งในเหตุผลสำหรับเรื่องนี้คือเรากำลังมีความชัดเจนเกี่ยวกับกระบวนการทำให้เป็นอนุกรมแทนที่จะใช้การสะท้อนเพื่ออนุมาน นอกจากนี้ยังหมายถึงเหตุผลที่รหัสได้รับการปรับปรุงอย่างมากสำหรับวัตถุประสงค์นี้

ดูตัวอย่างด้านล่าง (พัสดุ):

// 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วัตถุที่บรรจุได้ดังนี้:

// 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. Parcelableอินเตอร์เฟสใช้เวลามากกว่าในการติดตั้งเมื่อเทียบกับSerializableส่วนต่อประสาน
  3. Serializable ส่วนต่อประสานนั้นใช้งานง่ายกว่า
  4. Serializable อินเตอร์เฟสสร้างวัตถุชั่วคราวจำนวนมากและทำให้มีการรวบรวมขยะค่อนข้างน้อย
  5. Parcelable อาร์เรย์สามารถส่งผ่านทางเจตนาใน Android

2
@Sujith คุณหมายถึงอะไรโดยใช้การสะท้อน ? การสะท้อนคืออะไร
— AnV

11
@AbhinavVutukuri Reflection เป็นคำศัพท์สำหรับตรวจสอบวัตถุเขตข้อมูลและวิธีการในขณะใช้งานผ่าน Object.getClass () และอื่น ๆ
— FaultException

2
Serializables ดีกว่าสำหรับข้อมูลที่คงอยู่วัตถุที่สามารถตรวจจับได้ในทางกลับกันไม่ควรคงอยู่ มันเป็นการปฏิบัติที่เลวร้ายจริงๆ
— TheAnimatrix

2
@Sujith ตามที่มีมากกว่าหนึ่งคนได้ระบุวัตถุที่ parcelable ไม่สามารถคงอยู่ (เชื่อถือได้) แต่วัตถุที่สามารถทำให้เป็นอนุกรมได้ (ภายในขีด จำกัด ) เนื่องจากคำตอบของคุณคือการให้คะแนนสูงสุดและให้ความประทับใจในการครอบคลุมความแตกต่างที่สำคัญทั้งหมดคุณอาจจะพูดถึงประเด็นนั้น
— LarsH

4
ตอนนี้การนำ Parcelable ไปใช้งานได้เร็วที่สุดเท่าที่เป็น Serializable เพียงกด ALT + INSERT กับคลาสใดก็ตามที่ใช้ Parcelable ใน Android Studio และ IDE จะทำเช่นนั้น
— Ali Nem

183

Serializableเป็นอินเตอร์เฟส Java มาตรฐาน คุณเพียงแค่ทำเครื่องหมาย class Serializable โดยใช้ interface และ Java จะทำการ serialize มันโดยอัตโนมัติในบางสถานการณ์

Parcelableเป็นอินเทอร์เฟซเฉพาะสำหรับ Android ที่คุณใช้การทำให้เป็นอนุกรมด้วยตัวคุณเอง มันถูกสร้างขึ้นเพื่อให้มีประสิทธิภาพมากกว่าที่ Serializable และเพื่อแก้ไขปัญหาบางอย่างกับโครงร่างการทำให้เป็นอนุกรม Java เริ่มต้น

ฉันเชื่อว่า Binder และ AIDL ทำงานกับวัตถุ Parcelable

อย่างไรก็ตามคุณสามารถใช้วัตถุที่ปรับแต่งได้ใน Intents


1
ฉันจะทำให้เป็นอันดับของวัตถุที่พัสดุได้อย่างไร ฉันจะทำให้มันถาวรได้อย่างไร
— นรก

@Haded รับเนื้อหาของสถานะวัตถุและเก็บไว้ในไฟล์หรือฐานข้อมูล SQLLite Seriliasing มีประโยชน์สำหรับการทำให้อ็อบเจกต์สามารถถ่ายโอนระหว่างส่วนประกอบต่าง ๆ ใน Android หรือแอพพลิเคชั่นต่าง ๆ โดยสิ้นเชิง
— Jonathan

6
นี่คือคำอธิบายที่ดี ฉันยังสังเกตเห็นสิ่งนี้: "พัสดุไม่ใช่กลไกการทำให้เป็นอนุกรมทั่วไปวัตถุประสงค์คลาสนี้ (และ Parcelable API ที่สอดคล้องกันสำหรับการวางวัตถุโดยพลการลงในพัสดุ) ได้รับการออกแบบเป็นการขนส่ง IPC ประสิทธิภาพสูงดังนั้นจึงไม่เหมาะสมที่จะ วางข้อมูล Parcel ใด ๆ ลงในที่จัดเก็บข้อมูลถาวร: การเปลี่ยนแปลงในการใช้งานพื้นฐานของข้อมูลใด ๆ ใน Parcel สามารถทำให้ข้อมูลเก่าไม่สามารถอ่านได้ " developer.android.com/reference/android/os/Parcel.html
— Sam003

@Zishisheng มีความหมายอะไรกับวัตถุใด ๆ วัตถุประเภทใดที่เราสามารถใส่ลงในพัสดุได้
— hasnain_ahmad

วิธีการเกี่ยวกับการแปลงวัตถุเป็นสตริง json แทนด้วย gson?
— FOO

57

Parcelable vs Serializableฉันอ้างอิงสองตัวนี้

สำหรับ Java และ Kotlin

1) Java

ความเรียบง่ายต่อเนื่อง

Serializable คืออะไร

Serializable เป็นอินเตอร์เฟส Java มาตรฐาน มันไม่ได้เป็นส่วนหนึ่งของ Android SDK ความเรียบง่ายคือความงาม เพียงใช้อินเทอร์เฟซนี้ POJO ของคุณจะพร้อมที่จะข้ามจากกิจกรรมหนึ่งไปอีกกิจกรรมหนึ่ง

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;
}
}
  • ความสวยงามของซีเรียลไลซ์เซชันคือคุณต้องใช้อินเตอร์เฟส Serializable บนคลาสและลูก ๆ ของมันเท่านั้น เป็นอินเทอร์เฟซของตัวทำเครื่องหมายซึ่งหมายความว่าไม่มีวิธีในการใช้งาน Java จะพยายามอย่างเต็มที่ในการทำให้เป็นอนุกรมอย่างมีประสิทธิภาพ

  • ปัญหาของวิธีนี้คือใช้การสะท้อนและเป็นกระบวนการที่ช้า กลไกนี้มีแนวโน้มที่จะสร้างวัตถุชั่วคราวจำนวนมากและทำให้เกิดการรวบรวมขยะค่อนข้างน้อย

พัสดุ, ความเร็ว

พัสดุคืออะไร

พัสดุเป็นส่วนต่อประสานอื่น แม้จะเป็นคู่แข่ง (Serializable ในกรณีที่คุณลืม) มันเป็นส่วนหนึ่งของ Android SDK ตอนนี้พัสดุถูกออกแบบมาโดยเฉพาะในลักษณะที่ไม่มีการสะท้อนเมื่อใช้งาน นั่นเป็นเพราะเรากำลังชัดเจนมากสำหรับกระบวนการทำให้เป็นอันดับ

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

ตอนนี้ผู้ชนะคือ

ป้อนคำอธิบายรูปภาพที่นี่

ผลของการทดสอบที่ดำเนินการโดย Philippe Breault แสดงให้เห็นว่าพัสดุเร็วกว่าอนุกรม Serializable มากกว่า 10 เท่า วิศวกรของ Google คนอื่น ๆ ยืนอยู่ข้างหลังคำสั่งนี้เช่นกัน

ตามที่พวกเขาวิธีการ Serializable เริ่มต้นจะช้ากว่าพัสดุ และที่นี่เรามีข้อตกลงระหว่างทั้งสองฝ่าย! แต่มันไม่ยุติธรรมที่จะเปรียบเทียบทั้งสองเลย! เพราะด้วย Parcelable เรากำลังเขียนโค้ดที่กำหนดเอง รหัสที่สร้างขึ้นโดยเฉพาะสำหรับ POJO นั้น ดังนั้นไม่มีการสร้างขยะและผลลัพธ์จะดีกว่า แต่ด้วยวิธีการ Serializable เริ่มต้นเราพึ่งพากระบวนการ serialization อัตโนมัติของ Java เห็นได้ชัดว่ากระบวนการไม่ได้กำหนดเองเลยและสร้างขยะมากมาย! ดังนั้นผลลัพธ์ที่เลวร้ายยิ่ง

หยุดหยุด !!!! ก่อนตัดสินใจ

ขณะนี้มีอีกวิธีหนึ่ง กระบวนการอัตโนมัติทั้งหมดที่อยู่เบื้องหลัง 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;

และตอนนี้การเปรียบเทียบระหว่าง Parcelable และ Serializable ที่กำหนดเองดูเหมือนยุติธรรม! ผลลัพธ์อาจจะแปลกใจ! วิธีการ Serializable ที่กำหนดเองนั้นเร็วกว่า 3x สำหรับการเขียนและ 1.6x เร็วกว่าสำหรับการอ่านมากกว่าพัสดุ

แก้ไข: -----

2) การจัดลำดับ Kotlinx

Kotlinx Serialization Library

For Kotlin serialization need to add below dependency and plugin

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

apply plugin: 'kotlinx-serialization'

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

การทำให้เป็นอนุกรมทำได้ง่ายมากคุณต้องใส่คำอธิบายประกอบในคลาสที่ต้องการโดยมี@Serializableคำอธิบายประกอบด้านล่าง

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

สองคำอธิบายประกอบอื่น ๆ ที่ควรทราบและtransient optionalการใช้งานชั่วคราวจะทำให้ serializer ไม่สนใจฟิลด์นั้นและการใช้ตัวเลือกจะช่วยให้ serializer ไม่หยุดทำงานหากฟิลด์หายไป แต่ในเวลาเดียวกันจะต้องระบุค่าเริ่มต้น

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

หมายเหตุ : สิ่งนี้สามารถทำงานกับคลาสข้อมูลได้เช่นกัน

ทีนี้เพื่อใช้จริงในการดำเนินการลองมาเป็นตัวอย่างของวิธีการแปลง 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)
    }

สำหรับข้อมูลเพิ่มเติม


@Farhana ทำอย่างไรกับ data class ใน kotlin?
— Nisarg

@Nisarg ฉันได้เพิ่ม Kotlin Serializationไปดู
— Farhana

@Farhana นี่ฉลาดมาก ฉันต้องการย้ายไปทำงานที่ kotlin จริง ๆ แต่ข้อเสนอของฉันถูกปฏิเสธโดยผู้จัดการ ฉันสงสัยว่าฉันจะได้รับเกณฑ์มาตรฐานสำหรับ Serializable (ด้วยวิธีที่กำหนดเอง) ซึ่งคุณพูดว่าเร็วกว่า Parcelable 1.6 เท่าหรือไม่
— Abhinav Kulshreshtha

39

หากคุณต้องการเป็นพลเมืองที่ดีให้ใช้เวลาพิเศษในการใช้งาน Parcelable เพราะมันจะทำงานได้เร็วขึ้น 10 เท่าและใช้ทรัพยากรน้อยลง

อย่างไรก็ตามในกรณีส่วนใหญ่ความช้าของ Serializable จะไม่สามารถสังเกตเห็นได้ อย่าลังเลที่จะใช้ แต่โปรดจำไว้ว่าการทำให้เป็นอันดับเป็นสิ่งที่มีค่าใช้จ่ายสูง

หากคุณพยายามส่งรายการที่มีวัตถุอนุกรมต่อเนื่องหลายพันรายการเป็นไปได้ว่ากระบวนการทั้งหมดจะใช้เวลามากกว่าหนึ่งวินาที มันสามารถทำให้การเปลี่ยนภาพหรือการหมุนจากแนวตั้งเป็นแนวนอนกลายเป็นความรู้สึกที่ซบเซามาก

แหล่งที่มาถึงจุดนี้: http://www.developerphil.com/parcelable-vs-serializable/


32

ใน Parcelable นักพัฒนาเขียนโค้ดที่กำหนดเองสำหรับการทำมาร์ชชิ่งและ unmarshaling ดังนั้นมันจึงสร้างออบเจ็กต์ขยะน้อยลงเมื่อเปรียบเทียบกับการทำให้เป็นอนุกรม ประสิทธิภาพของ Parcelable over Serialization ช่วยปรับปรุง (เร็วขึ้นประมาณสองเท่า) เนื่องจากการใช้งานที่กำหนดเองนี้

Serializable เป็นอินเทอร์เฟซของตัวทำเครื่องหมายซึ่งหมายความว่าผู้ใช้ไม่สามารถรวบรวมข้อมูลตามข้อกำหนด ในการทำให้เป็นอนุกรมการดำเนินการ marshaling จะดำเนินการบน Java Virtual Machine (JVM) โดยใช้ Java reflection API สิ่งนี้จะช่วยระบุสมาชิกและพฤติกรรมของวัตถุ Java แต่ท้ายที่สุดก็สร้างวัตถุขยะจำนวนมาก ด้วยเหตุนี้กระบวนการทำให้เป็นอันดับจะช้าเมื่อเทียบกับ Parcelable

แก้ไข: ความหมายของ marshalling และ unmarshalling คืออะไร?

ในสองสามคำ "marshalling" หมายถึงกระบวนการแปลงข้อมูลหรือวัตถุที่เป็นไบต์ - สตรีมและ "unmarshalling" เป็นกระบวนการย้อนกลับของการแปลงไบต์ - สตรีม beack ข้อมูลหรือวัตถุดั้งเดิม การแปลงสามารถทำได้ผ่าน "อนุกรม"

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


คำอธิบายที่ดีงามแม้ไม่มีตัวอย่าง verbose สิ่งที่ฉันต้องการสำหรับการแก้ไข
— sud007

20

จริง ๆ แล้วฉันจะเป็นคนที่สนับสนุน Serializable ความแตกต่างของความเร็วนั้นไม่รุนแรงนักเนื่องจากอุปกรณ์ต่าง ๆ ดีกว่าหลายปีที่ผ่านมาและยังมีความแตกต่างที่ลึกซึ้งกว่า ดูโพสต์บล็อกของฉันเกี่ยวกับปัญหาสำหรับข้อมูลเพิ่มเติม


1
ขอบคุณสำหรับการแบ่งปัน ความซับซ้อนน้อยกว่าในการใช้การทำให้เป็นอนุกรมและจำเป็นต้องมีการตัดสินใจในกรณีที่หายากและเหมาะสมที่สุด
— Ankan-Zerob

2
มุมมองทางเลือกโดยเฉพาะอย่างยิ่งเมื่อสำรองข้อมูลกับการทดสอบและผลลัพธ์มีประโยชน์มาก ฉันต้องทำงานกับซอร์สโค้ด Parcelable ที่มีอยู่เป็นจำนวนมากและอาจทำให้บางส่วนของมันตอนนี้ที่ฉันได้อ่านโพสต์บล็อกของคุณ
— Les

14

พัสดุเป็นมาตรฐานในการพัฒนา Android แต่ไม่ใช่เพราะความเร็ว

แนะนำวิธีการถ่ายโอนข้อมูลแบบพัสดุภัณฑ์ แต่ถ้าคุณใช้ serializable อย่างถูกต้องตามที่แสดงในrepo นี้คุณจะเห็นว่าบางครั้ง serializable ได้เร็วขึ้นแล้วพัสดุ หรืออย่างน้อยก็กำหนดเวลาเปรียบได้

Parcelable เร็วกว่านั้นเป็น Serializable หรือไม่?

Java serialization ตามปกติบนอุปกรณ์ Android เฉลี่ย (ถ้าทำถูกต้อง *) เร็วกว่า Parcelable ประมาณ 3.6 เท่าสำหรับการเขียนและเร็วกว่า 1.6 เท่าสำหรับการอ่าน นอกจากนี้ยังพิสูจน์ให้เห็นว่า Java Serialization (ถ้าทำถูกต้อง) เป็นกลไกการจัดเก็บข้อมูลที่รวดเร็วที่ให้ผลลัพธ์ที่ยอมรับได้แม้จะมีกราฟวัตถุขนาดใหญ่ที่มีวัตถุ 11000 วัตถุที่มี 10 ฟิลด์แต่ละฟิลด์

* sidenote คือโดยปกติแล้วทุกคนที่สุ่มสี่สุ่มห้าระบุว่า "พัสดุเร็วกว่าข้าวต้มเร็วกว่า" เปรียบเทียบกับการจัดลำดับอัตโนมัติเริ่มต้นซึ่งใช้การสะท้อนมาก ๆ นี่เป็นการเปรียบเทียบที่ไม่ยุติธรรมเนื่องจาก Parcelable ใช้ขั้นตอนการเขียนข้อมูลไปยังสตรีมด้วยตนเอง (และซับซ้อนมาก) สิ่งที่ไม่ได้กล่าวถึงคือมาตรฐาน Java Serializable ตามเอกสารสามารถทำได้ด้วยตนเองโดยใช้วิธีการ writeObject () และ readObject () สำหรับข้อมูลเพิ่มเติมโปรดดู JavaDocs นี่คือวิธีที่ควรทำเพื่อประสิทธิภาพที่ดีที่สุด

ดังนั้นถ้า serializable เร็วกว่าและง่ายกว่าที่จะนำไปใช้ทำไมหุ่นยนต์ถึงมีทั้งหมด

เหตุผลคือรหัสพื้นเมือง พัสดุถูกสร้างขึ้นไม่เพียง แต่สำหรับการสื่อสารระหว่างกระบวนการ นอกจากนี้ยังสามารถนำมาใช้สำหรับการสื่อสาร intercode คุณสามารถส่งและรับวัตถุจากเลเยอร์ดั้งเดิม C ++ แค่นั้นแหละ.

คุณควรเลือกอะไร ทั้งสองจะทำงานได้ดี แต่ฉันคิดว่า Parcelable เป็นตัวเลือกที่ดีกว่าเพราะแนะนำโดย google และอย่างที่คุณเห็นจากกระทู้นี้ชื่นชมมากขึ้น


คุณสามารถระบุแหล่งที่มาของคุณได้หรือไม่ ฉันจะขอบคุณมันจริงๆ ขอบคุณ !!
— Archie G. Quiñones

2
คำตอบที่ผมได้จากนักพัฒนาที่มีประสบการณ์ที่ทำงานในโครงการ AOSP เกี่ยวข้องtwitter.com/bwdude เขาบอกว่ารหัส C ++ ดั้งเดิมสำหรับการสื่อสารกับ SDK เลเยอร์ใช้การใช้งาน Parcelable ของตัวเอง ฉันเดาว่าเขาพูดถึงandroid.googlesource.com/platform/frameworks/native/+/ชั้นนี้ ฉันรู้ว่านี่ไม่ใช่คำอธิบายที่ดีที่สุด แต่มันดีที่สุดที่ฉันมีตอนนี้ หากคุณจะพบสิ่งอื่นอย่าลืมโพสต์ไว้ที่นี่ =)
— Maksim Turaev

หวังว่าฉันจะสามารถโหวตคุณมากกว่าหนึ่งครั้ง ฉันเห็นผู้เชี่ยวชาญ Android และ Java ที่ยอดเยี่ยมแล้ว การไม่มีเอกสารช่วยป้องกันไฟแก็ซใด ๆ สำหรับ Serializable รู้สึกว่าสิ่งเหล่านี้เป็นผลของการส่งเสริม API เฉพาะ ขอบคุณ!
— pulp_fiction

11

1. ต่อเนื่องได้

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

อินเตอร์เฟซของอะไร

  • เป็นอินเตอร์เฟส Java มาตรฐาน

ความเร็ว

  • ช้ากว่าพัสดุ

2. พัสดุ

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

อินเตอร์เฟซของอะไร

  • เป็นอินเตอร์เฟส android.os
    • ซึ่งหมายความว่า Google พัฒนาพัสดุเพื่อประสิทธิภาพที่ดีขึ้นบน Android

ความเร็ว

  • เร็วขึ้น (เพราะเหมาะสำหรับการใช้งานในการพัฒนา Android)

> ในบทสรุป

ระวังว่า Serializable เป็นอินเตอร์เฟส Java มาตรฐานและ Parcelable สำหรับการพัฒนา Android


คุณควรเพิ่มการใช้งานของพวกเขาด้วย
— Anshul Tyagi

7

มีปัญหาด้านประสิทธิภาพบางประการเกี่ยวกับการจัดการและการแยกไฟล์ พัสดุภัณฑ์เร็วกว่า Serializable สองเท่า

กรุณาไปที่ลิงค์ต่อไปนี้:

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



4

การใช้งานของพัสดุสามารถทำได้เร็วขึ้นหากคุณใช้ปลั๊กอิน paracelable ใน android studio ค้นหาเครื่องกำเนิดรหัส Android Parcelable


3

อินเตอร์เฟส Serializable สามารถใช้วิธีเดียวกับ Parcelable หนึ่งซึ่งส่งผลให้มีประสิทธิภาพดีขึ้น (ไม่มาก) เพียงเขียนทับทั้งสองวิธีเหล่านี้เพื่อจัดการขั้นตอนการจัดเตรียมด้วยตนเองและยกเลิกการเรียงข้อมูลด้วยตนเอง:

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

ถึงกระนั้นมันก็ดูเหมือนว่าเมื่อพัฒนา Android พื้นเมืองการใช้ Android API เป็นวิธีที่จะไป

ดู:


2

ฉันตอบช้า แต่โพสต์ด้วยความหวังว่าจะช่วยผู้อื่น

ในแง่ของความเร็วParcelable > Serializable , แต่Customizableเป็นข้อยกเว้น มันเกือบจะอยู่ในช่วงของ 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

พัสดุเร็วกว่า Serializable ด้วย Binder เนื่องจากการสะท้อนการใช้งานแบบอนุกรมและทำให้ GC หลายตัว พัสดุเป็นการออกแบบเพื่อเพิ่มประสิทธิภาพในการผ่านวัตถุ

นี่คือลิงค์สำหรับอ้างอิง http://www.developerphil.com/parcelable-vs-serializable/


1

คุณสามารถใช้วัตถุที่สามารถทำให้เป็นอนุกรมได้ใน intents แต่ในเวลาที่ทำให้วัตถุ Parcelable เป็นอนุกรมมันสามารถให้ข้อยกเว้นที่ร้ายแรงเช่น NotSerializableException ไม่แนะนำให้ใช้กับอนุกรมหรือ Parcelable ดังนั้นจะเป็นการดีกว่าถ้าคุณขยาย Parcelable กับวัตถุที่คุณต้องการใช้กับชุดรวมและ intents เนื่องจากพัสดุนี้เป็นหุ่นยนต์เฉพาะจึงไม่มีผลข้างเคียงใด ๆ :)


0

serializable

Serializable เป็นอินเตอร์เฟซที่ทำเครื่องหมายได้หรือเราสามารถเรียกว่าเป็นอินเตอร์เฟสที่ว่างเปล่า ไม่มีวิธีการใด ๆ ที่นำมาใช้ล่วงหน้า Serializable จะเปลี่ยนวัตถุเป็น byte stream ดังนั้นผู้ใช้สามารถส่งผ่านข้อมูลระหว่างกิจกรรมหนึ่งไปยังกิจกรรมอื่น ข้อได้เปรียบหลักของ serializable คือการสร้างและการส่งผ่านข้อมูลเป็นเรื่องง่ายมาก แต่มันเป็นกระบวนการที่ช้าเมื่อเทียบกับพัสดุ

Parcelable

สามารถส่งพัสดุได้เร็วกว่าการจัดลำดับ พัสดุสามารถแปลงวัตถุเป็นไบต์และส่งผ่านข้อมูลระหว่างสองกิจกรรม การเขียนโค้ดที่สามารถใช้พัสดุทำได้ค่อนข้างซับซ้อนเล็กน้อยเมื่อเทียบกับการจัดลำดับ มันไม่ได้สร้างวัตถุชั่วคราวมากขึ้นขณะส่งข้อมูลระหว่างสองกิจกรรม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.