尝试使用自定义对象数组的Parcelable ArrayList时出现ClassCastException

时间:2014-04-18 07:16:30

标签: android parcelable

我正在尝试实施Parcelable而不是Serializable,因为它应该更有效率。

从我的MainActivity我想将通用类型ArrayList<LogChartData>的对象传递给同一个活动,以便我更改方向。

如果我越过这一个错误,我确信我会遇到更多的错误,但是现在当我尝试运行我的应用程序时,我正在接受,

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 个答案:

答案 0 :(得分:2)

您无法直接将String变量直接强制转换为Date对象,如此

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

您需要使用SimpleDateFormat并解析指定日期格式的String,然后存储在Date对象

假设您的日期格式为"yyyy-MM-dd"

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

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

答案 1 :(得分:1)

您必须使用writeToParcel(Parcel dest, int flags)方法。做这样的事

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

我不知道Date对象。它是Parcelable。我认为你必须使用SimpleDateFormat将其转换为字符串。

答案 2 :(得分:0)

LogEntries也应该实现Parcelable接口

假设:

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 ---*/
}

然后:

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 ---*/
}

您可以使用Date中的long值并相应地检索它