web-dev-qa-db-ja.com

ClassNotFoundExceptionをスローするKotlinパーセル可能クラス

このクラスのオブジェクトをRecyclerViewを介してあるアクティビティから別のアクティビティに渡すためにIntentのデータモデルとして使用するクラスがあります。それをParcelableにする必要がありました。

問題は、あるアクティビティから別のアクティビティにオブジェクトを送信して取得できることですアプリがクラッシュしないようにが、logcat画面にClassNotFoundExceptionをスローし続けます。

私は何が間違っているのですか?

----> Person.kt

_@Parcelize
class Person(var name: String, var username: String, var address: String, val avatar: Int) : Parcelable
_

----> MainActivity.kt内

_val intent = Intent(this, ProfilePage::class.Java)
        intent.putExtra("clicked_person",person)
        startActivity(intent)
_

---->。onCreate() in ProfilePAge.kt

_var person  = intent.getParcelableExtra<Person>("clicked_person") as Person
_

そしてException

_E/Parcel: Class not found when unmarshalling: com.example.testkot.kotlinapp.Person
                                         Java.lang.ClassNotFoundException: com.example.testkot.kotlinapp.Person
_

アプリはクラッシュせず、動作し続けますが、logcatに例外が表示されることに注意してください

7
codeKiller

コメントでソリューションをテストした後、以下は例外をスローせずに機能します

Parcelable経由でBundleを送信

val intent = Intent(this, ProfilePage::class.Java)
var bundle = Bundle()
bundle.putParcelable("selected_person",person)
intent.putExtra("myBundle",bundle)
startActivity(intent)

Parcelableの回復

val bundle = intent.getBundleExtra("myBundle")
var person  = bundle.getParcelable<Person>("selected_person") as Person

ただし、質問の古いコードとの違い、その古いコードが例外をスローする理由、およびこの新しいコードがスローしない理由はわかりません。

18
codeKiller

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)
}

使用法:

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

//Get parcel
val person: Person?  = intent.getParcel() //auto converts using Generics
3
Gunhan

これは、現時点ではKotlinとJavaの間の互換性の問題だと思います。Kotlinのみを使用し、定型文を使用しない簡単な解決策を見つけました。

val intent = Intent(this, ProfilePage::class.Java).apply {
    extras?.putParcellable("clicked_person",person)
}

startActivity(intent)

そして、使用する必要のある値を廃止するには、次のようにします。

var person = intent?.extras?.getParcellable<Person>("clicked_person")

注意:Personとしてキャストする必要はありません

2
Blake
var bundle = intent.extras
var person = bundle.getParcelable<Person>("selected_person")

上記のコードは私のために働いています。次のようにコードを短くすることができます。

var person = intent.extras.getParcelable<Person>("selected_person")
0
omujeebr

最初のアクティビティ:

 val intent = Intent(this@MainActivity, DetailsActivity::class.Java)
        intent.putExtra(Const.SELECTED_NOTE, noteList[position])
        startActivity(intent)

2番目のアクティビティ:

val note = intent.getParcelableExtra<Note>(Const.SELECTED_NOTE)

[〜#〜] Explain [〜#〜]:最初にParcelableデータを入力し、次のアクティビティでgetParcelableExtraを呼び出す必要があります! getParcelableExtraでは、Data class(ここでは)とKey Of Bundle(ここではConst.SELECTED_NOTE)を呼び出す必要があります。

0
sana ebadi