Android日积月累系列之四-android kotlin Parcelable 实现生成器

363 阅读2分钟

android kotlin Parcelable 实现生成器

原有的java类,实现Parcelable是很麻烦的,虽然有as插件帮助自动生成代码,但是新增或删除字段,还需要手动再生成代码。

public class ParcelableBean implements Parcelable {

    private int id;
    private String name;
    private long time;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    @Override
    public int describeContents() {
        return 0;
    }

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

    public ParcelableBean() {
    }

    protected ParcelableBean(Parcel in) {
        this.id = in.readInt();
        this.name = in.readString();
        this.time = in.readLong();
    }

    public static final Creator<ParcelableBean> CREATOR = new Creator<ParcelableBean>() {
        @Override
        public ParcelableBean createFromParcel(Parcel source) {
            return new ParcelableBean(source);
        }

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

kotlin-parcelize 插件后

@Parcelize
data class ParcelableBean(
    val id: Int? = null,
    val name: String? = null,
    val time: Long? = null,
):Parcelable

配置

添加 id 'kotlin-parcelize'

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'org.jetbrains.kotlin.kapt'
    id 'kotlin-parcelize'
}

当您使用 @Parcelize 为类添加注解时,系统会自动生成一个 Parcelable 实现,如以下示例所示:

import kotlinx.parcelize.Parcelize

@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable

支持的类型

@Parcelize 支持多种类型:

  • 基元类型(及其 boxed 版本)

  • 对象和枚举

  • StringCharSequence

  • Exception

  • SizeSizeFBundleIBinderIInterfaceFileDescriptor

  • SparseArraySparseIntArraySparseLongArraySparseBooleanArray

  • 所有 Serializable(包括 Date)和 Parcelable 实现

  • 所有受支持类型的集合:

    List(映射到ArrayList)

    Set(映射到LinkedHashSet)

    Map(映射到LinkedHashMap)

    • 此外,还有一些具体实现:ArrayListLinkedListSortedSetNavigableSetHashSetLinkedHashSetTreeSetSortedMapNavigableMapHashMapLinkedHashMapTreeMapConcurrentHashMap
  • 所有受支持类型的数组

  • 所有受支持类型的可为 null 版本

自定义 Parceler

如果系统不能直接支持您的类型,您可以为其写一个 Parceler 映射对象。

class ExternalClass(val value: Int)

object ExternalClassParceler : Parceler<ExternalClass> {
    override fun create(parcel: Parcel) = ExternalClass(parcel.readInt())

    override fun ExternalClass.write(parcel: Parcel, flags: Int) {
        parcel.writeInt(value)
    }
}

您可以使用 @TypeParceler@WriteWith 注解来应用外部 Parceler:

// Class-local parceler
@Parcelize
@TypeParceler<ExternalClass, ExternalClassParceler>()
class MyClass(val external: ExternalClass) : Parcelable

// Property-local parceler
@Parcelize
class MyClass(@TypeParceler<ExternalClass, ExternalClassParceler>() val external: ExternalClass) : Parcelable

// Type-local parceler
@Parcelize
class MyClass(val external: @WriteWith<ExternalClassParceler>() ExternalClass) : Parcelable

参考资料

kotlin parcelize