通过Parcelable传递对象时出现类型错误问题求助
嘿,这种Parcelable传参时的类型混淆坑我踩过好多次了,大概率是下面几个地方没处理对,咱们挨个排查:
1. 核对Parcelable核心方法的实现一致性
Parcelable的describeContents()和writeToParcel()+CREATOR的读取逻辑必须严格对应,两个类如果这里出了问题,很容易导致序列化/反序列化时的类型错乱:
describeContents():如果你的类不需要传递文件描述符这类特殊内容,直接返回0就行,别给两个类返回相同的非0值(除非是刻意的,但一般没必要)。writeToParcel()的写入顺序和CREATOR中createFromParcel()的读取顺序必须完全一致。比如你的Track类,写入时先写trackOwner,再写trackName,最后写sumDistance,那读取的时候必须按一模一样的顺序来。
给你贴一个Track类的标准实现示例:
public class Track implements Parcelable { private String trackOwner; private String trackName; private Double sumDistance; public final static String POINTTOPOINT = "POINTTOPOINT"; public final static String CIRCUIT = "CIRCUIT"; // 普通构造方法 public Track(String trackOwner, String trackName, Double sumDistance) { this.trackOwner = trackOwner; this.trackName = trackName; this.sumDistance = sumDistance; } // Parcel反序列化构造方法 protected Track(Parcel in) { // 读取顺序和writeToParcel完全对应 trackOwner = in.readString(); trackName = in.readString(); sumDistance = in.readDouble(); } public static final Creator<Track> CREATOR = new Creator<Track>() { @Override public Track createFromParcel(Parcel in) { return new Track(in); } @Override public Track[] newArray(int size) { return new Track[size]; } }; @Override public int describeContents() { return 0; // 无特殊内容返回0即可 } @Override public void writeToParcel(Parcel dest, int flags) { // 写入顺序要和读取顺序一致 dest.writeString(trackOwner); dest.writeString(trackName); dest.writeDouble(sumDistance); } }
另一个实现Parcelable的类也要严格遵循这个规则,不要随便打乱读写顺序。
2. 确认Intent传递的Key绝对不重复
这是最容易犯的低级错误!如果你给两个不同类的对象用了同一个Intent Extra Key,后面的对象会直接覆盖前面的,导致你取的时候拿到的是后传的那个,自然就会出现类型转换错误。
正确的传递方式应该是这样:
// 传递Track对象 Intent intent = new Intent(this, TargetActivity.class); intent.putExtra("EXTRA_TRACK_DATA", trackInstance); // 传递另一个Parcelable对象(假设是Route类) intent.putExtra("EXTRA_ROUTE_DATA", routeInstance); startActivity(intent);
接收的时候也要用对应的Key来取:
// 在TargetActivity中 Track track = getIntent().getParcelableExtra("EXTRA_TRACK_DATA"); Route route = getIntent().getParcelableExtra("EXTRA_ROUTE_DATA");
千万不要图省事用同一个Key(比如都叫"DATA"),这绝对会触发类型混淆。
3. 检查两个类的CREATOR是否指向正确类型
有时候复制粘贴Parcelable代码时,容易把A类的CREATOR不小心粘到B类里,导致B类反序列化出来的是A类对象,强制转换肯定报错。
比如第二个类的CREATOR必须是自己的类型:
public class Route implements Parcelable { // ... 类成员 public static final Creator<Route> CREATOR = new Creator<Route>() { @Override public Route createFromParcel(Parcel in) { return new Route(in); } @Override public Route[] newArray(int size) { return new Route[size]; } }; // ... 其他Parcelable方法 }
一定要确认CREATOR的泛型和返回的对象类型都是当前类的。
4. 清除缓存并重新编译
有时候Android Studio的缓存会导致奇怪的类加载问题,尤其是修改过Parcelable实现之后。可以试试这几步:
- 点击顶部菜单栏的
Build->Clean Project - 然后
Build->Rebuild Project - 实在不行就重启Android Studio,或者清除Gradle缓存(
File->Invalidate Caches...-> 勾选选项后重启)
把这些点都检查一遍,基本就能解决这个类型混淆的问题了。
内容的提问来源于stack exchange,提问作者ilia_bro
相关产品推荐
相关产品推荐

