android - Kotlin - IllegalArgumentException:指定为非空的参数为空
问题描述
我将数据传递给捆绑中的某个片段,并在接收它时抛出异常。恢复 Fragment 的状态时会发生此错误。
调用createFromParcel时,Intrinsics.checkParameterIsNotNull发生错误。模型中的所有不可为空的字段都会发生这种情况。
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)
属性.kt
@Parcelize
data class Property(
...
@Json(name = "RealtorImageUrl")
val realtorImageUrl: String
...
) : Parcelable
Kotlin 1.1.4,Android Extensions 插件使用 @Parcelize 提供 Parcelable 实现生成器。
属性列表片段.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)
}
}
...
}
我需要做什么来解决这个问题?
解决方案
由于realtorImageUrl
定义不为空,所以 kotlin 不允许将其设置为空。因此,唯一可能的方法是通过反射设置空值。Json 辅助库基于注释处理并使用反射来设置字段的值,因此问题肯定来自它们。
- 首先,我强烈建议您使用 google
Gson
。 - 其次,确保配置更改后json字符串不为null或为空。
- 第三,确保您在依赖项中使用
moshi-kotlin
(不是 simple )并向构建器moshi
添加实例。KotlinJsonAdapterFactory
moshi
构建.gradle:
implementation 'com.squareup.moshi:moshi-kotlin:1.8.0'
测试:
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()
最好使用withArguments
from anko为片段添加参数:
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
)
}
}
推荐阅读
- github - GitHub 操作在合并时运行两次
- python - 尝试从网站上抓取数据时,BeautifulSoup 似乎永远加载或永远不会返回任何内容
- google-cloud-platform - 是否可以通过 GCP 中的云功能或云运行来触发云存储?
- javascript - 根据自定义条件递归过滤树
- python - 数据框内存视图
- javascript - 页面在 React.js 中调整大小、滚动和键盘弹出时重新加载
- android - 通过 FileProvider 和 Intent 将缓存文件附加到 GMail 不起作用
- python - 通过子字符串将 Pandas 系列拆分为多列
- delphi - Build Group 无法与 Delphi 中的语言项目一起构建主项目
- python - 如何在不同的python版本中运行代码