2014-10-09 106 views
5

运行,创建一个Singleton 从创建Activity返回到第一Activity,当我得到这个错误的内部对象,并将其存储到ArrayList第二活动后。包含JodaTime序列化的自定义对象对象转换成JSON

的logcat:

10-09 15:00:48.125: E/AndroidRuntime(4266): FATAL EXCEPTION: main 
10-09 15:00:48.125: E/AndroidRuntime(4266): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nanospark.cnc/com.nanospark.cnc.ContactCreateActivity}: java.lang.RuntimeException: Failed to invoke public org.joda.time.Chronology() with no args 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread.access$600(ActivityThread.java:141) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.os.Looper.loop(Looper.java:137) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread.main(ActivityThread.java:5103) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at java.lang.reflect.Method.invoke(Method.java:525) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at dalvik.system.NativeStart.main(Native Method) 
10-09 15:00:48.125: E/AndroidRuntime(4266): Caused by: java.lang.RuntimeException: Failed to invoke public org.joda.time.Chronology() with no args 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:107) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:173) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:95) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:183) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:95) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:183) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.Gson.fromJson(Gson.java:805) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.Gson.fromJson(Gson.java:770) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.Gson.fromJson(Gson.java:719) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.nanospark.cnc.GlobalData.retrieveGlobalDataFromStorage(GlobalData.java:92) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.nanospark.cnc.ContactCreateActivity.onCreate(ContactCreateActivity.java:38) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.Activity.performCreate(Activity.java:5133) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  ... 11 more 
10-09 15:00:48.125: E/AndroidRuntime(4266): Caused by: java.lang.InstantiationException: can't instantiate class org.joda.time.Chronology 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at java.lang.reflect.Constructor.constructNative(Native Method) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at java.lang.reflect.Constructor.newInstance(Constructor.java:417) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:104) 
10-09 15:00:48.125: E/AndroidRuntime(4266):  ... 27 more 

辛格尔顿代码做JSON写:

public void storeGlobalData(Context context){ 
    mPrefs = context.getSharedPreferences("com.nanospark.cnc", Context.MODE_PRIVATE); 
    preferenceEditor = mPrefs.edit(); 
    Gson gson = new Gson(); 
    //Transform the ArrayLists into JSON Data. 
    String machineProfileListJSON = gson.toJson(getMachineProfileList()); 
    String contactInfoListJSON = gson.toJson(getContactInfoList()); 
    String eventInfoListJSON = gson.toJson(getEventInfoList()); 
    preferenceEditor.putString("machineProfileListJSONData", machineProfileListJSON); 
    preferenceEditor.putString("contactInfoListJSONData", contactInfoListJSON); 
    preferenceEditor.putString("eventInfoListJSONData", eventInfoListJSON); 
    //Commit the changes. 
    preferenceEditor.commit(); 

} 
public void retrieveGlobalDataFromStorage(Context context){ 
    mPrefs = context.getSharedPreferences("com.nanospark.cnc", Context.MODE_PRIVATE); 
    if(mPrefs.contains("machineProfileListJSONData")){ 

     Gson gson = new Gson(); 
     String machineProfileListJSON = mPrefs.getString("machineProfileListJSONData", ""); 
     String contactInfoListJSON = mPrefs.getString("contactInfoListJSONData", ""); 
     String eventInfoListJSON = mPrefs.getString("eventInfoListJSONData", ""); 
      Type machineProfileListType = new TypeToken<ArrayList<MachineProfile>>() {}.getType(); 
      machineProfileList = (gson.fromJson(machineProfileListJSON, machineProfileListType)); 

      Type contactInfoListType = new TypeToken<ArrayList<ContactInfo>>() {}.getType(); 
      contactInfoList = gson.fromJson(contactInfoListJSON, contactInfoListType); 

      Type eventListType = new TypeToken<ArrayList<Event>>() {}.getType(); 
      eventInfoList = gson.fromJson(eventInfoListJSON, eventListType); 
    } 
} 

报告事件类别正在试图写:

package com.nanospark.cnc; 

import java.util.ArrayList; 

import org.joda.time.LocalDate; 
import org.joda.time.LocalTime; 
public class ReportEvent extends Event { 

    public ReportEvent(String eventTitle,String eventDescription,int assignedPin, String trackingType, 
      LocalDate startDate, LocalDate endDate, boolean watchAllDay, 
      LocalTime startTime, LocalTime endTime, ArrayList<String> selectedDays, 
      ArrayList<ContactInfo> selectedContact, String formatChoice, 
      ReportTimeSpec reportTimingConfig) { 
     super(eventTitle,eventDescription, assignedPin, trackingType, startDate, endDate, watchAllDay, 
       startTime, endTime, selectedDays, selectedContact, formatChoice, 
       reportTimingConfig); 
     // TODO Auto-generated constructor stub 
    } 

} 

通用事件类报告事件延伸:

package com.nanospark.cnc; 

import java.util.ArrayList; 
import java.util.Calendar; 

import org.joda.time.LocalDate; 
import org.joda.time.LocalTime; 


public class Event { 
    String eventTitle; 
    String eventDescription; 
    int assignedPin; 
    String trackingType; 
    LocalDate startDate; 
    LocalDate endDate; 
    boolean watchAllDay; 
    LocalTime startTime; 
    LocalTime endTime; 
    ArrayList<String> selectedDays = new ArrayList<String>(); 
    ArrayList<ContactInfo> selectedContact = new ArrayList<ContactInfo>(); 
    String formatChoice; 
    ReportTimeSpec reportTimingConfigs; 

    public Event(){ 

    } 
    public Event(String eventTitle, String eventDescription, int assignedPin, String trackingType, 
      LocalDate startDate, LocalDate endDate, boolean watchAllDay, 
      LocalTime startTime, LocalTime endTime, ArrayList<String> selectedDays, 
      ArrayList<ContactInfo> selectedContact, String formatChoice, ReportTimeSpec reportTimingConfigs) { 
     this.eventTitle = eventTitle; 
     this.eventDescription = eventDescription; 
     this.assignedPin = assignedPin; 
     this.trackingType = trackingType; 
     this.startDate = startDate; 
     this.endDate = endDate; 
     this.watchAllDay = watchAllDay; 
     this.startTime = startTime; 
     this.endTime = endTime; 
     this.selectedDays = selectedDays; 
     this.selectedContact = selectedContact; 
     this.formatChoice = formatChoice; 
     this.reportTimingConfigs = reportTimingConfigs; 
    } 



    public String getEventTitle() { 
     return eventTitle; 
    } 

    public void setEventTitle(String eventTitle) { 
     this.eventTitle = eventTitle; 
    } 

    public String getEventDescription() { 
     return eventDescription; 
    } 

    public void setEventDescription(String eventDescription) { 
     this.eventDescription = eventDescription; 
    } 

    public ReportTimeSpec getReportTimingConfigs() { 
     return reportTimingConfigs; 
    } 

    public void setReportTimingConfigs(ReportTimeSpec reportTimingConfigs) { 
     this.reportTimingConfigs = reportTimingConfigs; 
    } 

    public int getAssignedPin() { 
     return assignedPin; 
    } 

    public void setAssignedPin(int assignedPin) { 
     this.assignedPin = assignedPin; 
    } 

    public String getTrackingType() { 
     return trackingType; 
    } 

    public void setTrackingType(String trackingType) { 
     this.trackingType = trackingType; 
    } 

    public LocalDate getStartDate() { 
     return startDate; 
    } 

    public void setStartDate(LocalDate startDate) { 
     this.startDate = startDate; 
    } 

    public LocalDate getEndDate() { 
     return endDate; 
    } 

    public void setEndDate(LocalDate endDate) { 
     this.endDate = endDate; 
    } 

    public boolean isWatchAllDay() { 
     return watchAllDay; 
    } 

    public void setWatchAllDay(boolean watchAllDay) { 
     this.watchAllDay = watchAllDay; 
    } 

    public LocalTime getStartTime() { 
     return startTime; 
    } 

    public void setStartTime(LocalTime startTime) { 
     this.startTime = startTime; 
    } 

    public LocalTime getEndTime() { 
     return endTime; 
    } 

    public void setEndTime(LocalTime endTime) { 
     this.endTime = endTime; 
    } 

    public ArrayList<String> getSelectedDays() { 
     return selectedDays; 
    } 

    public void setSelectedDays(ArrayList<String> selectedDays) { 
     this.selectedDays = selectedDays; 
    } 

    public ArrayList<ContactInfo> getSelectedContact() { 
     return selectedContact; 
    } 

    public void setSelectedContact(ArrayList<ContactInfo> selectedContact) { 
     this.selectedContact = selectedContact; 
    } 

    public String getFormatChoice() { 
     return formatChoice; 
    } 

    public void setFormatChoice(String formatChoice) { 
     this.formatChoice = formatChoice; 
    } 

    public ReportTimeSpec getReportTimeSpec() { 
     return reportTimingConfigs; 
    } 

    public void setReportTimeSpec(ReportTimeSpec reportTimingConfigs) { 
     this.reportTimingConfigs = reportTimingConfigs; 
    } 
    @Override 
    public String toString(){ 
     return this.eventTitle; 
    } 

} 
+0

现在我知道我可以创建一个自定义序列化器,例如这里看到的:https://github.com/gkopff/gson-javatime-serialisers – Tukajo 2014-10-12 22:41:37

+0

但是,我的问题是 - 我如何扩展他的示例序列化类来覆盖一个包含'LocalTime'和'DateTime'对象的对象? – Tukajo 2014-10-12 22:42:04

+0

请提交更多的代码,当调用此代码并传递内容时,很难说出此代码之外发生了什么。 – apoorvk 2014-10-12 22:58:44

回答

13

来自https://github.com/gkopff/gson-javatime-serialisers的转换器用于java.time来自Java8的类,例如, java.time.LocalDate

但您需要转换器org.joda.time来自第三方零件库的类。你可以为它创建自定义的转换器,如:

转换为org.joda.time.LocalDate

public class LocalDateSerializer implements JsonDeserializer<LocalDate>, JsonSerializer<LocalDate> 
{ 
    private static final DateTimeFormatter DATE_FORMAT = ISODateTimeFormat.date(); 

    @Override 
    public LocalDate deserialize(final JsonElement je, final Type type, 
          final JsonDeserializationContext jdc) throws JsonParseException 
    { 
     final String dateAsString = je.getAsString(); 
     if (dateAsString.length() == 0) 
     { 
     return null; 
     } 
     else 
     { 
     return DATE_FORMAT.parseLocalDate(dateAsString);   
     } 
    } 

    @Override 
    public JsonElement serialize(final LocalDate src, final Type typeOfSrc, 
           final JsonSerializationContext context) 
    { 
     String retVal; 
     if (src == null) 
     { 
     retVal = ""; 
     } 
     else 
     { 
     retVal = DATE_FORMAT.print(src); 
     } 
     return new JsonPrimitive(retVal); 
    } 
} 

转换为org.joda.time.LocalTime

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.getAsString(); 
     if (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); 
    } 

} 

用法

public void retrieveGlobalDataFromStorage(Context context) 
{ 
// ... 

    final GsonBuilder builder = new GsonBuilder() 
     .registerTypeAdapter(LocalDate.class, new LocalDateSerializer()) 
     .registerTypeAdapter(LocalTime.class, new LocalTimeSerializer()); 
    final Gson gson = builder.create(); 
// ... 
+0

这是否适用于同时包含LocalDate和LocalTime的对象(即ReportEvent对象)?这应该不重要,因为这两种类型都注册到GsonBuilder是否正确? – Tukajo 2014-10-13 12:54:51

+0

@Tukajo是的,正确的,这将适用于'ReportEvent' – Ilya 2014-10-13 13:52:09

+0

当它的计时器过期时,我将奖赏你的赏金@Ilya。谢谢,我会给这个镜头。 – Tukajo 2014-10-13 14:25:30