从 Parcelable 类中读取和写入 java.util.Date

Posted

技术标签:

【中文标题】从 Parcelable 类中读取和写入 java.util.Date【英文标题】:Reading and writing java.util.Date from Parcelable class 【发布时间】:2014-01-27 20:06:08 【问题描述】:

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

【问题讨论】:

【参考方案1】:

使用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());

    

【讨论】:

但是序列化操作会消耗很多性能。如何克服这一点? 你真的应该使用 long 来实现,因为 Serializable 不利于性能,这在旧设备上很明显。您可能还想看看 Joda,因为它包含许多有用的工具,并且有一个我经常觉得更有用的 DateTime 对象。 现在可以了。我更喜欢使用 long 而不是序列化。 @Mesut 太好了! congs 你有你的解决方案。 @JockyDoe 它不会。打包和取消打包时字段的顺序很重要。因此,请检查您是否对两个字段使用相同的顺序。【参考方案2】:

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()

【讨论】:

【参考方案3】:

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

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 之类的值。【参考方案4】:

试试这个(Kotlin):

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)
    

【讨论】:

【参考方案5】:

Date 类实现Serializable...

所以你可以写

parcel.writeSerializable(java.util.Date)

你可以像这样阅读

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

【讨论】:

虽然这可行,但我建议 SO 的用户使用 longs 查看答案。【参考方案6】:

试试这个方法::

写::

yourParse.writeSerializable(YourGivenDate)

阅读::

Date myDate = yourParse.readSerializable();

【讨论】:

以上是关于从 Parcelable 类中读取和写入 java.util.Date的主要内容,如果未能解决你的问题,请参考以下文章

传递读取的 FD parcelable:何时关闭?

从 parcelable 对象中读取字符串返回 null

java.lang.RuntimeException: Parcelable 遇到 IOException 写入可序列化对象 (name = io.realm.StationAndLocationMo

如何使用 ArrayList<Parcelable> 正确实现 Parcelable?

无法从 onActivityReenter 中的 Intent 读取 Parcelable

无法解决“Parcelable 遇到写入可序列化对象的 IOException”