从Parcelable类读写java.util.Date


78

我正在使用Parcelable类。如何java.util.Date在此类上读写对象?

Answers:


184

在日期可序列化的地方使用writeSerializable。(但不是一个好主意。请参见下面的另一种更好的方法

@Override
public void writeToParcel(Parcel out, int flags) {
   // Write object
   out.writeSerializable(date_object);

}

private void readFromParcel(Parcel in) {
   // Read object
    date_object = (java.util.Date) in.readSerializable();

}

但是序列化操作会消耗很多性能。如何克服这个问题?

因此,更好的用法是在编写时将日期转换为Long,然后读取Long并传递给Date构造函数以获取Date。见下面的代码

   @Override
    public void writeToParcel(Parcel out, int flags) {
       // Write long value of Date
       out.writeLong(date_object.getTime());

    }

    private void readFromParcel(Parcel in) {
       // Read Long value and convert to date
        date_object = new Date(in.readLong());

    }

3
但是序列化操作会消耗很多性能。如何克服这个问题?
Mesut 2014年

1
您确实应该使用long来完成此操作,因为Serializable对性能不利,这在较旧的设备上很明显。您可能还想看看Joda,因为它包含许多有用的工具,并且具有我经常发现更有用的DateTime对象。
格雷厄姆·史密斯

现在可以。我更喜欢使用long而不是序列化。
Mesut 2014年

@Mesut太好了!聪,您已找到解决方案。
Pankaj Kumar 2014年

1
@JockyDoe不会。拆分和取消拆分时字段的顺序很重要。因此,请检查两个字段的顺序是否相同。
Pankaj Kumar

18

Kotlin中,我们可以为Parcel创建扩展名-最简单的解决方案。

fun Parcel.writeDate(date: Date?) {
    writeLong(date?.time ?: -1)
}

fun Parcel.readDate(): Date? {
    val long = readLong()
    return if (long != -1L) Date(long) else null
}

并使用它

parcel.writeDate(date)
parcel.readDate()

14

使用date.getTime()获取长格式:

public class MiClass implements Parcelable {
    Date date;

    public MiClass(Date date) {
        this.date = date;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(date != null ? date.getTime() : -1);
    }

    protected MiClass(Parcel in) {
        long tmpDate = in.readLong();
        this.date = tmpDate == -1 ? null : new Date(tmpDate);
    }

    public static final Parcelable.Creator<MiClass> CREATOR = new Parcelable.Creator<MiClass>() {
        public MiClass createFromParcel(Parcel source) {
            return new MiClass(source);
        }

        public MiClass[] newArray(int size) {
            return new MiClass[size];
        }
    };
}

这是一个很好的解决方案,但不适用于1970年1月1日之前的日期。-1L实际上是代表1/1/1970之前一毫秒的有效值。因此,我宁愿使用Long.MIN_VALUE之类的值来提高安全性。
BladeCoder

2

试试这个(科特琳):

data class DateParcel(val date: Date?):Parcelable {
constructor(parcel: Parcel) : this(parcel.readValue(Date::class.java.classLoader) as? Date
)

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeValue(date)
}

override fun describeContents(): Int {
    return 0
}

companion object CREATOR : Parcelable.Creator<DateParcel> {
    override fun createFromParcel(parcel: Parcel): DateParcel {
        return DateParcel(parcel)
    }

    override fun newArray(size: Int): Array<DateParcel?> {
        return arrayOfNulls(size)
    }
}}

1

Date类工具Serializable...

所以你可以写

parcel.writeSerializable(java.util.Date)

你可以读像

java.util.Date date = (java.util.Date)parcel.readSerializable();

1
虽然这将起作用,但我建议SO Takea的用户使用long来查看答案。
格雷厄姆·史密斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.