我正在使用带有GSON转换器的RetroFit 1.9,到目前为止我一直很好用。现在我正在尝试编组List
中收到的Parcelable
个自定义Callback
个对象,我遇到了ClassCastException
:
02-02 09:53:49.921 13030-13030/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 13030
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to android.os.Parcelable
at android.os.Parcel.writeTypedList(Parcel.java:1166)
at com.example.common.util.ParcelableUtil.marshall(ParcelableUtil.java:37)
at com.example.app.service.WearableMessageService$1.success(WearableMessageService.java:130)
at com.example.app.service.WearableMessageService$1.success(WearableMessageService.java:120)
at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
这是我的回调方法:
new Callback<List<MyObject>>() {
@Override
public void success(List<MyObject> objects, Response response) {
mByteArray = ParcelableUtil.marshall(objects);
}
@Override
public void success(RetrofitError error) {
Timber.w("Failed to retrieve events, with message " + error.getMessage());
}
}
所以我在success
方法中添加了一个for循环,就在我调用ParcelableUtil.marshall()
之前,测试为什么我得到的LinkedTreeMap
对象列表而不是我的对象:
for(MyObject object : objects) {
Timber.d(object.getTitle());
}
这不仅打印出每个对象的正确标题,奇迹般地其余代码也能正常工作! ParcelableUtil
不再抛出错误,我收到一个字节数组,以后我可以完全解组。
LinkedTreeMap
个对象列表在循环中观察之后如何更改为我的对象列表?为什么我首先得到LinkedTreeMap
个对象的列表?这里发生了什么?
MyObject
上课:
public class MyObject implements Parcelable {
@SerializedName("title") private String mTitle;
@SerializedName("location") private String mLocation;
@SerializedName("start_date") private Date mStartDate;
@SerializedName("end_date") private Date mEndDate;
public MyObject() {
/* Required empty constructor */
}
public Event(Parcel in) {
mTitle = in.readString();
mLocation = in.readString();
mStartDate = new Date(in.readLong());
mEndDate = new Date(in.readLong());
}
public String getTitle() {
return mTitle;
}
public String getLocation() {
return mLocation;
}
public void getStartDate() {
return mStartDate();
}
public void getEndDate() {
return mEndDate();
}
@Override
public in describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mTitle);
dest.writeString(mLocation);
dest.writeLong(mStartDate.getTime());
dest.writeLong(mEndDate.getTime());
}
public static final Creator<MyObject> CREATOR = new Creator<MyObject>() {
@Override
public MyObject createFromParcel(Parcel in) {
return new MyObject(in);
}
@Override
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
}
MyObject
的示例JSON Feed:
{
"items": [
{
"title":"Object 1"
"location":"Location 1"
"start_date":"2016-02-02 15:30:00"
"end_date":"2016-02-02 19:00:00"
}
{
"title":"Object 2"
"location":"Location 2"
"start_date":"2016-02-02 18:00:00"
"end_date":"2016-02-03 18:00:00"
}
]
}
正在使用的GSON TypeAdapterFactory
:
public class DataAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
delegate.write(out, value);
}
@Override
public void read(JsonReader in) throws IOException {
JsonElement jsonElement = elementAdapter.read(in);
if(jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if(jsonObject.has("items") && jsonObject.get("items".isJsonArray()) {
jsonElement = jsonObject.getAsJsonArray("items");
}
return delegate.fromJsonTree(jsonElement);
}
}
}.nullSafe();
}
}
答案 0 :(得分:0)
-keep public class com.example.common.model.MyObject
-keep public class * implements com.example.common.model.MyObject
-keepclassmembers class com.example.common.model.MyObject {
<methods>;
}
我相信在我的情况下我只需要第一行,但我认为其他的只会覆盖我的基础。