Android Kotlin报BadParcelableException:反序列化类未找到求助
解决android.os.BadParcelableException: ClassNotFoundException when unmarshalling问题
这种异常通常是Parcelable类的加载或序列化环节出了问题,结合你用@Parcelize的场景,我整理了几个针对性的解决方案,你可以一步步排查:
1. 确认Parcelize插件配置正确
@Parcelize依赖kotlin-parcelize插件才能正常生成序列化代码,先检查app模块的build.gradle(或build.gradle.kts)是否添加了必要配置:
// Groovy版本 plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-parcelize' // 必须添加这个插件 } // Kotlin DSL版本 plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("kotlin-parcelize") }
同时确保你的Kotlin版本和Android Gradle Plugin(AGP)版本兼容,比如Kotlin 1.8+搭配AGP 7.4+是比较稳妥的组合。
2. 检查MusicTrack类的定义细节
虽然用了@Parcelize,但一些小细节可能导致序列化失败:
- 确保
MusicTrack是public类,不要用internal修饰——跨组件(比如Activity之间)传递数据时,目标组件需要能访问到这个类的定义。 - 确认所有属性都支持序列化:你的
fileUri: Uri是系统自带的Parcelable类型,没问题;其他属性都是基本类型或String,也符合要求。如果后续添加自定义类型,要确保它也实现了Parcelable。 - 不要给类添加额外的非主构造函数(除非也用
@Parcelize处理),data class的主构造函数要包含所有需要序列化的属性。
3. 规范数据传递与接收的代码
传递ArrayList<Parcelable>时,类型擦除可能导致接收端无法正确识别类,要注意两点:
- 传递和接收时用完全一致的键名,比如你用
Config.MusicConfig.MUSIC_TRACKS作为键,接收端必须用同一个键取值。 - 接收时显式指定泛型类型,比如在目标Activity中:
val musicList = intent.getParcelableArrayListExtra<MusicTrack>(Config.MusicConfig.MUSIC_TRACKS)
如果是Fragment之间传递,通过arguments获取时也要指定泛型:
val musicList = arguments?.getParcelableArrayList<MusicTrack>(Config.MusicConfig.MUSIC_TRACKS)
4. 清理缓存并重建项目
旧的编译缓存可能导致类加载异常,试试这些操作:
- 执行Android Studio的
Build > Clean Project,再执行Build > Rebuild Project - 卸载设备上的应用,清除缓存后重新安装
5. 手动实现Parcelable(兜底方案)
如果以上步骤都没解决问题,可以暂时去掉@Parcelize,手动实现Parcelable接口排查是否是注解处理的问题,示例代码如下:
data class MusicTrack( val id: Long, val title: String, val albumId: String, val artist: String, val duration: String, val trackArt: String = "", val fileUri: Uri ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readLong(), parcel.readString() ?: "", parcel.readString() ?: "", parcel.readString() ?: "", parcel.readString() ?: "", parcel.readString() ?: "", parcel.readParcelable(Uri::class.java.classLoader) ?: Uri.EMPTY ) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeLong(id) parcel.writeString(title) parcel.writeString(albumId) parcel.writeString(artist) parcel.writeString(duration) parcel.writeString(trackArt) parcel.writeParcelable(fileUri, flags) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<MusicTrack> { override fun createFromParcel(parcel: Parcel): MusicTrack { return MusicTrack(parcel) } override fun newArray(size: Int): Array<MusicTrack?> { return arrayOfNulls(size) } } }
按照这个流程排查,应该能解决你的ClassNotFoundException问题。
内容的提问来源于stack exchange,提问作者Veeresh Charantimath




