I have an object called ReportEvent that accepts LocalTime as well as LocalDate from the JodaTime API / framework. This ReportEvent can be written to JSON using the google GSON conversion API. However, JodaTime partial deserialization causes problems.
Logcat error report:
10-16 13:23:01.812: E/AndroidRuntime(8884): FATAL EXCEPTION: main 10-16 13:23:01.812: E/AndroidRuntime(8884): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nanospark.cnc/com.nanospark.cnc.MainActivity}: java.lang.IllegalArgumentException: Invalid format: "{"iChronology":{"iBase":{"iMinDa..." 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.access$600(ActivityThread.java:141) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.os.Handler.dispatchMessage(Handler.java:99) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.os.Looper.loop(Looper.java:137) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.main(ActivityThread.java:5103) 10-16 13:23:01.812: E/AndroidRuntime(8884): at java.lang.reflect.Method.invokeNative(Native Method) 10-16 13:23:01.812: E/AndroidRuntime(8884): at java.lang.reflect.Method.invoke(Method.java:525) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 10-16 13:23:01.812: E/AndroidRuntime(8884): at dalvik.system.NativeStart.main(Native Method) 10-16 13:23:01.812: E/AndroidRuntime(8884): Caused by: java.lang.IllegalArgumentException: Invalid format: "{"iChronology":{"iBase":{"iMinDa..." 10-16 13:23:01.812: E/AndroidRuntime(8884): at org.joda.time.format.DateTimeFormatter.parseLocalDateTime(DateTimeFormatter.java:854) 10-16 13:23:01.812: E/AndroidRuntime(8884): at org.joda.time.format.DateTimeFormatter.parseLocalDate(DateTimeFormatter.java:798) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.LocalDateSerializer.deserialize(LocalDateSerializer.java:32) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.LocalDateSerializer.deserialize(LocalDateSerializer.java:1) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:95) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:183) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:805) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:770) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:719) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.GlobalData.retrieveGlobalDataFromStorage(GlobalData.java:118) 10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.MainActivity.onCreate(MainActivity.java:35) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.Activity.performCreate(Activity.java:5133) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175) 10-16 13:23:01.812: E/AndroidRuntime(8884): ... 11 more
Relevant sections of code:
LocalTime serializer / deserializer.
package com.nanospark.cnc; import java.lang.reflect.Type; import org.joda.time.LocalTime; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; public class LocalTimeSerializer implements JsonDeserializer<LocalTime>, JsonSerializer<LocalTime> { private static final DateTimeFormatter TIME_FORMAT = ISODateTimeFormat.timeNoMillis(); @Override public LocalTime deserialize(final JsonElement je, final Type type, final JsonDeserializationContext jdc) throws JsonParseException { final String dateAsString = je.toString(); if (je.isJsonNull() || dateAsString.length() == 0) { return null; } else { return TIME_FORMAT.parseLocalTime(dateAsString); } } @Override public JsonElement serialize(final LocalTime src, final Type typeOfSrc, final JsonSerializationContext context) { String retVal; if (src == null) { retVal = ""; } else { retVal = TIME_FORMAT.print(src); } return new JsonPrimitive(retVal); } }
LocalDate serializer / deserializer.
public class LocalDateSerializer implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> { private static final String PATTERN = "yyyy-MM-dd"; final DateTimeFormatter fmt = DateTimeFormat.forPattern(PATTERN); @Override public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) { String retVal = fmt.print(src); Log.v("MY LOCALDATE SERIALIZED", retVal); return new JsonPrimitive(retVal); } @Override public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Log.v("MY LOCALDATE DESERIALIZED",json.toString()); return fmt.parseLocalDate(json.toString()); } }
source share