Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีทำให้ Custom Object เป็น Parcelable ใน Android

ตัวอย่างนี้สาธิตวิธี ทำให้ Custom Object เป็น Parcelable ใน Android

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่ใน Android Studio

ไปที่ File → New Project และกรอกรายละเอียดที่จำเป็นทั้งหมด

ขั้นตอนที่ 2: เพิ่มโค้ดใน res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:gravity="center"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <Button
        android:id="@+id/parcleObject"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="27dp"
        android:text="Click here" />
</LinearLayout>

ขั้นตอนที่ 3: เพิ่มโค้ดใน src/MainActivity.java

package com.example.myapplication;

import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    ParcelableObject sample;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.parcleObject).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sample = new ParcelableObject("Sairamkrishna Mammahe");
                Toast.makeText(MainActivity.this, sample.getName(), Toast.LENGTH_LONG).show();
            }
        });
    }
}

ขั้นตอนที่ 4: สร้าง ParcelableObject.java

package com.example.myapplication;

import android.os.Parcel;
import android.os.Parcelable;

public class ParcelableObject implements Parcelable {
    private String name;

    // Constructor สำหรับสร้างจาก Parcel (Unmarshalling)
    protected ParcelableObject(Parcel in) {
        this.name = in.readString();
    }

    // Constructor ปกติ
    public ParcelableObject(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // CREATOR - จำเป็นสำหรับ Parcelable
    public static final Creator<ParcelableObject> CREATOR = new Creator<ParcelableObject>() {
        @Override
        public ParcelableObject createFromParcel(Parcel in) {
            return new ParcelableObject(in);
        }

        @Override
        public ParcelableObject[] newArray(int size) {
            return new ParcelableObject[size];
        }
    };

    @Override
    public int describeContents() {
        return 0; // 0 = ไม่มีไฟล์พิเศษ (File Descriptor)
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
    }
}

การทดสอบแอปพลิเคชัน

รันแอปพลิเคชันบนอุปกรณ์ Android จริง ใน Android Studio คลิกไอคอน Run เลือกอุปกรณ์ แล้วตรวจสอบหน้าจอเริ่มต้น

วิธีทำให้ Custom Object เป็น Parcelable ใน Android

คลิกปุ่ม จะสร้าง Parcelable Object และแสดงชื่อ

วิธีทำให้ Custom Object เป็น Parcelable ใน Android

คำอธิบาย Parable Components

Component หน้าที่
CREATOR Static Field สำหรับสร้าง Object จาก Parcel (Unmarshalling)
createFromParcel(Parcel) สร้าง Object Instance จาก Parcel Data
newArray(int size) สร้าง Array ของ Parcelable Object ขนาด size
describeContents() Bitmask บอกว่าเป็น Parcelable ประเภทไหน (0=ทั่วไป, CONTENTS_FILE_DESCRIPTOR=มี FD)
writeToParcel(Parcel, flags) เขียนข้อมูล Field ลง Parcel (Marshaling)
Constructor (Parcel in) อ่านข้อมูลจาก Parcel ตามลำดับเดียวกับ writeToParcel

เมธอด Parcel สำหรับ Type ต่างๆ

// Primitive
dest.writeInt(intVal);
dest.writeLong(longVal);
dest.writeFloat(floatVal);
dest.writeDouble(doubleVal);
dest.writeBoolean(boolVal);
dest.writeByte(byteVal);

// String & CharSequence
dest.writeString(stringVal);
dest.writeCharSequence(charSeqVal);

// Bundle
dest.writeBundle(bundleVal);

// Parcelable
dest.writeParcelable(parcelableVal, flags);

// Array/List
dest.writeStringArray(stringArray);
dest.writeList(listVal); // ต้องเป็น List<Parcelable> หรือ Serializable

// SparseArray
dest.writeSparseArray(sparseArrayVal);

วิธีลด Boilerplate (Modern Approach)

Kotlin: @Parcelize (แนะนำมาก)

@Parcelize
data class User(
    val id: Int,
    val name: String,
    val email: String,
    val isActive: Boolean
) : Parcelable

Java: AutoParcel Library

@AutoParcel
public abstract class User implements Parcelable {
    public abstract int id();
    public abstract String name();
    public abstract String email();
    public abstract boolean isActive();
    
    public static User create(int id, String name, String email, boolean isActive) {
        return new AutoParcel_User(id, name, email, isActive);
    }
}

Android Studio: Generate Parcelable (Code → Generate → Parcelable)

IDE จะสร้าง Boilerplate ให้อัตโนมัติ (แต่ต้อง Update เองเมื่อเพิ่ม Field)

Parcelable vs Serializable - สรุป

  • Parcelable - เร็ว, เหมาะ Android IPC (Intent, Bundle, Binder), แนะนำ
  • Serializable - ช้า, ใช้ได้ทั่วไป Java, เหมาะ File/Network/Cross-Process