Login Activity示例中的checkParameterIsNotNull错误

我正在尝试在Android Studio中使用标准样本启动kotlin。 首先,我使用Login Activity模板创建一个新项目,然后将其转换为使用kotlin。 但是我有这个字符串中的运行时 (不编译)错误:

loaderManager.initLoader(0, null, this) 

错误列表:

 Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter bundle 

由于LoaderManager.initLoader(int, Bundle, LoaderManager.LoaderCallbacks)是Java代码,因此Kotlin将其参数视为Int, Bundle!, LoaderManager.LoaderCallbacks<D!>!) 。 这些惊叹号是Kotlin 对平台类型的表示 。 Bundle! 是指“ Bundle还是Bundle? ”。 即Kotlin指出它不知道一个参数是非空还是可空的。

Android具有Java可空性注释 (即@NonNull@Nullable ),可用于为编译器等指定此功能,但这些功能尚未在此处使用。 如果是的话,Kotlin会推断这个类型是Bundle还是Bundle? 取决于哪个注释是存在的。

Android的args: Bundle!文档args: Bundle! 说它是可选的,即args: Bundle? (但是Kotlin编译器不能推断这个,因为它缺少@NonNull注解)。 如果你检查抛出异常的完整堆栈跟踪,我怀疑你会发现一个Kotlin函数接收args: Bundle但应该接收args: Bundle?

即如果你有类似的东西

 override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor> = TODO() 

那么它应该是

 override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> = TODO() 

因为Kotlin编译器为前者插入非空值检查,而不是后者。

请参阅Null-Safety和平台类型 – 从Kotlin – Kotlin编程语言中调用Java以获取更多详细信息。

答案很简单,只需将null替换为空Bundle()

 loaderManager.initLoader(0, Bundle(), this) 

但是我不明白为什么kotlin不能即时处理这个问题。

确切的答案是修改onCreateLoader函数

override fun onCreateLoader(i: Int, bundle: Bundle?): Loader<Cursor>

 loaderManager.initLoader(0,myBundle ?: Bundle(),this) 

如果myBundle为null, loadermanager将使用Bundle()