Kotlin parcelable类抛出ClassNotFoundException

cod*_*ler 7 parcelable android-intent kotlin

我有一个类,我用它作为我的数据模型RecyclerView,以便将此类的对象从一个活动传递到另一个活动,Intent我必须通过它Parcelable

现在的问题是我能够将对象从一个活动发送到另一个活动并检索它,这样应用程序就不会崩溃,而是继续投入ClassNotFoundExceptionlogcat屏幕.

我究竟做错了什么?

----> Person.kt

@Parcelize
class Person(var name: String, var username: String, var address: String, val avatar: Int) : Parcelable
Run Code Online (Sandbox Code Playgroud)

---->在MainActivity.kt中

val intent = Intent(this, ProfilePage::class.java)
        intent.putExtra("clicked_person",person)
        startActivity(intent)
Run Code Online (Sandbox Code Playgroud)

---->.onCreate()在ProfilePAge.kt中

var person  = intent.getParcelableExtra<Person>("clicked_person") as Person
Run Code Online (Sandbox Code Playgroud)

而且 Exception

E/Parcel: Class not found when unmarshalling: com.example.testkot.kotlinapp.Person
                                         java.lang.ClassNotFoundException: com.example.testkot.kotlinapp.Person
Run Code Online (Sandbox Code Playgroud)

请记住,应用程序不会崩溃,它会继续工作,但会在logcat中显示异常

cod*_*ler 15

在评论中测试解决方案后,以下工作不会抛出任何异常

发送Parcelable通道Bundle

val intent = Intent(this, ProfilePage::class.java)
var bundle = Bundle()
bundle.putParcelable("selected_person",person)
intent.putExtra("myBundle",bundle)
startActivity(intent)
Run Code Online (Sandbox Code Playgroud)

恢复 Parcelable

val bundle = intent.getBundleExtra("myBundle")
var person  = bundle.getParcelable<Person>("selected_person") as Person
Run Code Online (Sandbox Code Playgroud)

但是,我不知道我的旧代码在问题中的区别以及为什么旧代码抛出异常以及为什么这个新代码不抛出

  • 我赞成……这很奏效。由于某些原因,当您使用Intent.putExtra(CustomParcellableClass)时,它不会存储类加载器信息。无论如何,谢谢您的解决方案:D (2认同)

Gun*_*han 5

为了方便您在没有任何警告的情况下使用 Kotlin Parcelables,我准备了以下扩展函数。

fun Intent.putParcel(key: String = "parcel_key", parcel: Parcelable) {
    val bundle = Bundle()
    bundle.putParcelable(key, parcel)
    this.putExtra("parcel_bundle", bundle)
}

fun <T : Parcelable> Intent.getParcel(key: String = "parcel_key"): T? {
    return this.getBundleExtra("parcel_bundle")?.getParcelable(key)
}
Run Code Online (Sandbox Code Playgroud)

用法:

//Put parcel
intent.putParcel(parcel = Person()) //any Parcalable

//Get parcel
val person: Person?  = intent.getParcel() //auto converts using Generics
Run Code Online (Sandbox Code Playgroud)