You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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,但一些小细节可能导致序列化失败:

  • 确保MusicTrackpublic类,不要用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

火山引擎 最新活动