このクラスのオブジェクトを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に例外が表示されることに注意してください
コメントでソリューションをテストした後、以下は例外をスローせずに機能します
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
ただし、質問の古いコードとの違い、その古いコードが例外をスローする理由、およびこの新しいコードがスローしない理由はわかりません。
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
これは、現時点では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としてキャストする必要はありません
var bundle = intent.extras
var person = bundle.getParcelable<Person>("selected_person")
上記のコードは私のために働いています。次のようにコードを短くすることができます。
var person = intent.extras.getParcelable<Person>("selected_person")
最初のアクティビティ:
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)を呼び出す必要があります。