Lesen und Schreiben von java.util.Date aus der Parcelable-Klasse

79

Ich arbeite mit der Paketklasse. Wie kann ich java.util.DateObjekte zu und von dieser Klasse lesen und schreiben ?

Mesut
quelle

Antworten:

186

Verwenden Sie writeSerializable, wobei Date Serializable ist. ( Aber keine gute Idee. Siehe unten für einen anderen besseren Weg )

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

}

Serialisierungsvorgänge verbrauchen jedoch viel Leistung. Wie kann das überwunden werden?

Daher ist es besser, das Datum beim Schreiben in Long zu konvertieren, Long zu lesen und an den Date-Konstruktor zu übergeben, um das Datum abzurufen. Siehe unten Code

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

    }
Pankaj Kumar
quelle
3
Serialisierungsvorgänge verbrauchen jedoch viel Leistung. Wie kann das überwunden werden?
Mesut
1
Sie sollten es wirklich mit Longs tun, da Serializable nicht gut für die Leistung ist, was sich auf älteren Geräten bemerkbar macht. Vielleicht möchten Sie sich auch Joda ansehen, da es viele nützliche Tools enthält und ein DateTime-Objekt enthält, das ich oft nützlicher finde.
Graham Smith
Jetzt ist es ok. Ich bevorzuge es, lange zu verwenden, anstatt zu serialisieren.
Mesut
@ Mesut Großartig! congs du hast deine lösung.
Pankaj Kumar
1
@ JockyDoe wird es nicht. Reihenfolge der Felder beim Parzellieren und Aufheben der Parzellierung. Überprüfen Sie daher, ob Sie für beide Felder dieselbe Reihenfolge verwenden.
Pankaj Kumar
18

In Kotlin können wir eine Erweiterung für Parcel erstellen - die einfachste Lösung.

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

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

Und benutze es

parcel.writeDate(date)
parcel.readDate()
Pavel Shorokhov
quelle
14

Verwenden Sie date.getTime (), um das Langformat abzurufen :

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];
        }
    };
}
App-SoftwareFactory
quelle
Dies ist eine gute Lösung, funktioniert jedoch bei Daten vor dem 1.1.1970 nicht ordnungsgemäß. -1L ist tatsächlich ein gültiger Wert, der eine Millisekunde vor dem 1.1.1970 darstellt. Daher würde ich zur besseren Sicherheit lieber einen Wert wie Long.MIN_VALUE verwenden.
BladeCoder
2

Versuchen Sie dies (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)
    }
}}
Shyam Kumar
quelle
1

DateKlasse implementiert Serializable...

so kannst du schreiben

parcel.writeSerializable(java.util.Date)

und du kannst gerne lesen

java.util.Date date = (java.util.Date)parcel.readSerializable();
Gopal Gopi
quelle
1
Während dies funktionieren wird, schlage ich Benutzern von SO Takea vor, die Antwort mit Longs zu betrachten.
Graham Smith
0

Versuchen Sie dies auf diese Weise ::

für schreiben ::

yourParse.writeSerializable(YourGivenDate)

zum lesen ::

Date myDate = yourParse.readSerializable();
Satyaki Mukherjee
quelle