1

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;
    }
}

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks. My date format is like Tue Apr 01 13:22:05 GMT+05:30 2014. So should I use SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy"); ?
You may refer the symbols here
I am getting syntax error at format.parse because readValue is an object. Do you mean this.chartDate = format.parse((String) (in.readValue(LogChartData.class.getClassLoader()))); ?
Yes, in your case you need to do like that.
Thanks. I did that. One more thing- "Is it necessary to use writeToParcel" ? My code is working without the use of that.
|
1

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 .

5 Comments

error at dest.writeParcelableArray(data, flags); - "Bound mismatch: The generic method writeParcelableArray(T[], int) of type Parcel is not applicable for the arguments (LogEntries[], int). The inferred type LogEntries is not a valid substitute for the bounded parameter <T extends Parcelable>"
I am not getting error if I don't use writeToParcel(Parcel dest, int flags). Then why to use that ?
the object LogEntries is parceleble or not.
No, the class LogEntries isn't parcelable. So I have to make this also parcelable and also need to fill overridden writeToParcel there as well?
It also generated writeToParcel method. Do I use it for the class LogEntries as well ?
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.