android-studio - 如何将 Java 方法引用代码转换为 Kotlin

标签 android-studio kotlin java-8 android-livedata method-reference

我在 Java 中有这段代码:

mViewModel.getSetupData().observe(this, this::updateTime);

updateTime 方法接受一个参数。 将此代码转换为 Kotlin 时,以下内容不起作用:

mViewModel?.getSetupData()?.observe(this, ::updateTime)

IDE(android studio)提示

Type mismatch. Required: Observer. Found KFunction1.

有什么线索吗?

最佳答案

出于某种原因,Kotlin 在提供 observe 重载方面不够聪明:

// Java declaration
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)

现在在 Kotlin 中我们可以通过两种方式调用这个方法:

// Default Kotlin conversion [ #1 ]
fun observe(owner : LifecycleOwner, observer : Observer<in T>)

// SAM conversions [ #2 ]
fun observe(owner: () -> Lifecycle, observer : (T) -> Unit)

我们缺少的是介于两者之间的东西,我们只为观察者参数提供函数。

如果您已经依赖于 Android KTX 模块,即 androidx.fragment:fragment-ktx(或至少 androidx.lifecycle:lifecycle-livedata-core-ktx ) 下面的扩展应该已经可以访问了。否则你可以快速添加它:

// custom extension with function observer argument [ #3 ]
@MainThread inline fun <T> LiveData<T>.observe(
    owner: LifecycleOwner,
    crossinline onChanged: (T) -> Unit
): Observer<T> {
    val wrappedObserver = Observer<T> { t -> onChanged.invoke(t) }
    observe(owner, wrappedObserver)
    return wrappedObserver
}

下面是调用的区别:

// reusable observer object
val myObserver = Observer<TimeMeasurement> { updateTime(it) }

// function that updates time
fun updateTime(time : TimeMeasurement){
    // update views with time
}

override fun onCreate(savedInstanceState: Bundle?) {
    /* ... */

    // default call [ #1 ]
    mViewModel.liveData.observe(this, myObserver)
    // default call but with object expression for observer [ #1 ]
    mViewModel.liveData.observe(this, Observer { updateTime(it) })
    // alternatively [ #1 ]
    mViewModel.liveData.observe(this, Observer(::updateTime))

    // SAM conversions, lets us pass function reference or a lambda [ #2 ]
    // in this case first argument is a lambda as well and it returns lifecycle
    mViewModel.liveData.observe({ lifecycle }, ::updateTime)

    // extension function call where we pass function reference as second argument [ #3 ]
    mViewModel.liveData.observe(this, ::updateTime)
    // or using lambda [ #3 ]
    mViewModel.liveData.observe(this) { updateTime(it) }
}

关于android-studio - 如何将 Java 方法引用代码转换为 Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57698979/

相关文章:

android - Google Drive Android API ConnectionResult 错误

android - 如何在 Kotlin 中处理 "lock"静态对象

java - 将 DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL) 与 LocalTime 实例一起使用时出现 DateTimeException

java - 过滤器映射上的 JDK8 lambda NullPointerException

Android studio appengine 端点不包含构建器

android - 我尝试在我的安卓设备上运行 ionic 应用程序,但出现错误

gradle - Kotlin & Gradle - 确保类路径中有 kotlin-reflect.jar

android - Kotlin Flow - 有没有类似于 LiveData 的 emitSource 的东西?

java - 在 Java 8 中将匿名内部方法转换为 Lambda

java - Android Studio 错误 : package com. sun.xxx.xxx。不存在