Question

I’m trying to implement Parcelable instead of Serializable as it’s supposed to be more efficient.

From my MainActivity I want to pass the object of generic type ArrayList<LogChartData> to the same activity, so that I get it on orientation change.

If I get past this one error I’m sure I’ll run in to a lot more of them, but right now when I try to run my app I’m getting,

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.testapp.util.LogChartData.<init>(LogChartData.java:60)
at com.testapp.util.LogChartData.<init>(LogChartData.java:59)
at com.testapp.util.LogChartData$1.createFromParcel(LogChartData.java:51)
at com.testapp.util.LogChartData$1.createFromParcel(LogChartData.java:1)
at android.os.Parcel.readParcelable(Parcel.java:2103)
at android.os.Parcel.readValue(Parcel.java:1965)

MainActivity.java--

    ArrayList<LogChartData> logss = new ArrayList<LogChartData>();

@Override
    public void onSaveInstanceState(final Bundle outState) {
        outState.putParcelableArrayList("logss", logss);
        outState.putParcelableArrayList("alert", alert);
        outState.putBoolean("isRotate", true);
        super.onSaveInstanceState(outState);
    }


  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        if (savedInstanceState != null) {

            try
            {
                logss = savedInstanceState.getParcelableArrayList("logss");
                alert = savedInstanceState.getParcelableArrayList("alert");
                isRotate = savedInstanceState.getBoolean("isRotate");
            }
            catch(ClassCastException e)
            {
                e.printStackTrace();
            }

            if(!isRotate)
              someFunctionCall();

                    // More code here..
        }
}

LogCharData.java --

public class LogChartData implements Parcelable {

    public Date chartDate = null;
    public ArrayList<LogEntries> logs = new ArrayList<LogEntries>();

    public LogChartData(Date chartDate, ArrayList<LogEntries> logs) {
        super();
        this.chartDate = chartDate;
        this.logs = logs;
    }

    public LogChartData() {
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {

    }

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

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

    private LogChartData(Parcel in) {
        this.chartDate = 
    (Date)in.readValue(LogChartData.class.getClassLoader()); //Error Here..
        in.readList(logs, LogChartData.class.getClassLoader());

    }

    public Date getChartDate() {
        return chartDate;
    }

    public void setChartDate(Date chartDate) {
        this.chartDate = chartDate;
    }

    public ArrayList<LogEntries> getLogs() {
        return logs;
    }

    public void setLogs(ArrayList<LogEntries> logs) {
        this.logs = logs;
    }
}
Was it helpful?

Solution 3

LogEntries should implement Parcelable interface as well

Suppose:

public class LogEntries implements Parcelable {

    private String log;

    public LogEntries() {}

    public LogEntries(String log) {
        this.log = log;
    }

    public String getLog() {
        return log;
    }
    public void setLog(String log) {
        this.log = log;
    }

    /*--- INIT parcelable code ---*/
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    public void readFromParcel(Parcel source) {
        this.log = (String)source.readValue(String.class.getClassLoader());
    }

    /* Parceling constructor */
    public LogEntries(Parcel source) {
        this();
        readFromParcel(source);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(log);
    }

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

        @Override
        public LogEntries[] newArray(int size) {
            return new LogEntries[size];
        }
    };
    /*--- END parcelable code ---*/
}

Then:

public class LogChartData implements Parcelable {

    public Date chartDate = null;
    public ArrayList<LogEntries> logs = new ArrayList<LogEntries>();

    public LogChartData(Date chartDate, ArrayList<LogEntries> logs) {
        super();
        this.chartDate = chartDate;
        this.logs = logs;
    }

    public LogChartData() {}

    public Date getChartDate() {
        return chartDate;
    }

    public void setChartDate(Date chartDate) {
        this.chartDate = chartDate;
    }

    public ArrayList<LogEntries> getLogs() {
        return logs;
    }

    public void setLogs(ArrayList<LogEntries> logs) {
        this.logs = logs;
    }


    /*--- INIT parcelable code ---*/
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if(chartDate!=null) {
            dest.writeLong(chartDate.getTime());
        }
        else {
            dest.writeLong(0);
        }
        if(logs!=null) {
            dest.writeInt(logs.size()); // specify the number of logs
            dest.writeTypedList(logs);
        }
        else {
            dest.writeInt(-1); // specify there are no logs
        }
    }

    public LogChartData(Parcel source) {
        this();
        readFromParcel(source);
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    public void readFromParcel(Parcel source) {
        long timeMillis = source.readLong();
        if(timeMillis!=0) {
            this.chartDate = new Date(timeMillis);
        }
        else {
            this.chartDate = null;
        }

        int logsSize = source.readInt();
        if(logsSize>-1) {
            this.logs = new ArrayList<LogEntries>(logsSize);
            if(logsSize>0) {
                source.readTypedList(logs, LogEntries.CREATOR);
            }
        }
        else {
            this.logs = null;
        }
    }

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

        @Override
        public LogChartData[] newArray(int size) {
            return new LogChartData[size];
        }
    };
    /*--- END parcelable code ---*/
}

where you can use the long value from Date and retrieve it accordingly

OTHER TIPS

You cannot Directly cast the String variable directly to the Date Object like this

(Date)in.readValue(LogChartData.class.getClassLoader());

You need to use SimpleDateFormat and parse the String from Specified DateFormat and then Stored in the Date Object

Suppose if your Date as the format of "yyyy-MM-dd"

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

this.chartDate= format.parse(in.readValue(LogChartData.class.getClassLoader()));

you have to use writeToParcel(Parcel dest, int flags) method. do something like this

public LogChartData(Parcel source) {
    Parcelable[] parcelables = source.readParcelableArray(Thread
            .currentThread().getContextClassLoader());

      for (Parcelable parcelable : parcelables) {
        logs.add((LogEntries) parcelable);
     }
   }


@Override
public void writeToParcel(Parcel dest, int flags) {

    LogEntries[] data = new LogEntries[getLogs().size()];
    for (int i = 0; i < data.length; i++) {
          data[i] = getLogs().get(i);
    }
    dest.writeParcelableArray(data, flags);
}

I don't know about Date object. it is Parcelable or not . I think you have to convert it into string using SimpleDateFormat .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top