Je transmets des données à un fragment de la liasse et, lors de la réception, lève l'exception. Cette erreur se produit lors de la restauration de l'état de Fragment.
Une erreur se produit dans Intrinsics.checkParameterIsNotNull lorsque createFromParcel est appelé. Cela se produit avec tous les champs non nullables dans Model.
Caused by Java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.b.h.b, parameter realtorImageUrl
at com.Android.app.ui.common.model.Property.(Unknown Source:16)
at com.Android.app.ui.common.model.Property$Creator.createFromParcel(Unknown Source:637)
at Android.os.Parcel.readParcelable(Parcel.Java:2797)
at Android.os.Parcel.readValue(Parcel.Java:2691)
at Android.os.Parcel.readArrayMapInternal(Parcel.Java:3058)
at Android.os.BaseBundle.unparcel(BaseBundle.Java:257)
at Android.os.BaseBundle.getInt(BaseBundle.Java:961)
at me.yokeyword.fragmentation.SupportFragmentDelegate.onCreate(SourceFile:93)
at me.yokeyword.fragmentation.SupportFragment.onCreate(SourceFile:48)
at Android.support.v4.app.Fragment.performCreate(SourceFile:2331)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1386)
at Android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(SourceFile:1759)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1827)
at Android.support.v4.app.FragmentManagerImpl.dispatchStateChange(SourceFile:3244)
at Android.support.v4.app.FragmentManagerImpl.dispatchCreate(SourceFile:3194)
at Android.support.v4.app.Fragment.restoreChildFragmentState(SourceFile:1444)
at Android.support.v4.app.Fragment.onCreate(SourceFile:1415)
at me.yokeyword.fragmentation.SupportFragment.onCreate(SourceFile:47)
at Android.support.v4.app.Fragment.performCreate(SourceFile:2331)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1386)
at Android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(SourceFile:1759)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1827)
at Android.support.v4.app.FragmentManagerImpl.dispatchStateChange(SourceFile:3244)
at Android.support.v4.app.FragmentManagerImpl.dispatchCreate(SourceFile:3194)
at Android.support.v4.app.FragmentController.dispatchCreate(SourceFile:184)
at Android.support.v4.app.FragmentActivity.onCreate(SourceFile:355)
at Android.support.v7.app.AppCompatActivity.onCreate(SourceFile:84)
at me.yokeyword.fragmentation.SupportActivity.onCreate(SourceFile:38)
at com.Android.app.ui.home.HomeActivity.onCreate(SourceFile:47)
at Android.app.Activity.performCreate(Activity.Java:7174)
at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1220)
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2908)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:3030)
at Android.app.ActivityThread.-wrap11(Unknown Source)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1696)
at Android.os.Handler.dispatchMessage(Handler.Java:105)
at Android.os.Looper.loop(Looper.Java:164)
at Android.app.ActivityThread.main(ActivityThread.Java:6938)
at Java.lang.reflect.Method.invoke(Method.Java)
at com.Android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.Java:327)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1374)
Property.kt
@Parcelize
data class Property(
...
@Json(name = "RealtorImageUrl")
val realtorImageUrl: String
...
) : Parcelable
Kotlin 1.1.4, le plug-in Android Extensions fournit un générateur d'implémentation Parcelable utilisant @Parcelize.
PropertyListFragment.kt
override fun showPropertyDetails(property: Property) {
(parentFragment as PropertySearchResultFragment).start(
PropertyDetailsFragment.newInstance(property)
)
}
PropertyDetailsFragment.kt
class PropertyDetailsFragment{
...
companion object {
fun newInstance(property: Property) = PropertyDetailsFragment().withArgs {
putParcelable(INT_EXTRA_PROPERTY, property)
}
}
...
}
Que dois-je faire pour résoudre le problème?
Puisque la variable realtorImageUrl
est définie, et non null, kotlin ne permet pas de la définir comme nulle. Par conséquent, le seul moyen de le faire est de définir la valeur null par réflexion. Les bibliothèques d'assistance Json sont basées sur le traitement des annotations et sur l'utilisation de la réflexion pour définir les valeurs des champs. Le problème vient donc d'eux.
Gson
.moshi-kotlin
(pas simple moshi
) dans les dépendances et ajoutez une instance de KotlinJsonAdapterFactory
au générateur moshi
.build.gradle:
implementation 'com.squareup.moshi:moshi-kotlin:1.8.0'
Test:
val json = "{\"RealtorImageUrl\": \"http://www.gstatic.com/tv/thumb/persons/667736/667736_v9_ba.jpg\"}"
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory()) // com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
.build()
val jsonAdapter = moshi.adapter(Property::class.Java) as JsonAdapter<Property>
val property = jsonAdapter.fromJson(json) as Property
supportFragmentManager.beginTransaction()
.replace(R.id.container, PropertyDetailsFragment.newInstance(property))
.commit()
Il vaut mieux utiliser withArguments
de anko pour mettre les arguments du fragment:
PropertyDetailsFragment.kt:
class PropertyDetailsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val property = arguments?.getParcelable(KEY_EXTRA_PROPERTY) as Property
val realtorImageUrl = property.realtorImageUrl
}
companion object {
private const val KEY_EXTRA_PROPERTY = "KEY_EXTRA_PROPERTY"
fun newInstance(property: Property) = PropertyDetailsFragment().withArguments(
KEY_EXTRA_PROPERTY to property
)
}
}
Eh bien, ce n'est peut-être pas la solution parfaite, mais cela peut résoudre votre problème. Vous pouvez rendre votre propriété nullable et ajouter simplement un contrôle nul chaque fois que vous y accédez.
Vous n'avez qu'à initialiser une variable comme celle-ci
Property.kt
@Parcelize
data class Property(
...
@Json(name = "RealtorImageUrl")
val realtorImageUrl: String
...
) : Parcelable
PropertyListFragment.kt
override fun showPropertyDetails(property: Property?) {
(parentFragment as PropertySearchResultFragment).start(
PropertyDetailsFragment.newInstance(property)
)
}
Et dans PropertyDetailsFragment.kt
class PropertyDetailsFragment{
...
companion object {
fun newInstance(property: Property?) = PropertyDetailsFragment().withArgs {
property?.let{
putParcelable(INT_EXTRA_PROPERTY, property)
}
}
}
...
}
Pouvez-vous essayer d'utiliser @field: Json (name = "RealtorImageUrl") et vérifier si cela fonctionne alors?
Vérifiez également si vous avez ajouté la fabrique appropriée KotlinJsonAdapterFactory ()
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()