Kotlin中带参数的回调函数

10

我刚开始学习Kotlin,请多多指教 :)

我有一个类负责获取一些数据并通知主要活动需要更新其用户界面。

因此我在我的DataProvider.kt中创建了一个函数:

      fun getPeople(fromNetwork: Boolean, results: ((persons: Array<Person>, error: MyError?) -> Unit)) {

        // do some stuff stuff
        val map = hashMapOf(
                "John" to "Doe",
                "Jane" to "Smith"
        )

        var p = Person(map)
        val persons: Array <Person> = arrayOf (p)
        results(persons, null)
    }

因此我希望能从我的活动中调用它,但我找不到正确的语法!:

    DataProvider.getPeople(
            true,
            results =
    )

我尝试了很多方法,但我只想获取我的人员数组和可选错误,以便我可以更新UI。

目标是在我的数据提供程序中执行异步代码,以便我的活动可以等待它。

有什么想法吗?非常感谢任何帮助。

2个回答

13

这实际上取决于你如何定义回调函数。如果你使用一个独立的函数,使用::运算符。首先(当然),我应该解释一下语法:

(//these parenthesis are technically not necessary
(persons: Array<Person>, error: MyError?)//defines input arguments: an Array of Person and a nullable MyError
     -> Unit//defines the return type: Unit is the equivalent of void in Java (meaning no return type)
)

所以这种方法的定义如下:

fun callback(persons: Array<CustomObject>, error: Exception?){
    //Do whatever
}

你可以这样调用它:

DataProvider.getPeople(
    true,
    results = this::callback
)

但是,如果您使用匿名回调函数,情况就有些不同了。这也使用lambda:

getPeople(true, results={/*bracket defines a function. `persons, error` are the input arguments*/persons, error ->  {
        //do whatever
    }})

1
非常感谢您,能否告诉我匿名回调函数和独立函数之间的区别?哪一个更好? - user2434385
1
没有一个比另一个更好,你使用哪个取决于你的喜好,以及你是否会在其他地方使用它。如果你要多次编写代码或将方法作为非回调方法调用(或作为不同调用的回调),请使用独立方法。否则,请使用匿名函数。但实际上并没有什么“规则”(这只是我的个人偏好),所以你可以选择任何你喜欢的。 - Zoe stands with Ukraine

4

是的,Kotlin有一种很好的使用回调函数的方式。下面我将展示一个示例,说明我如何使用它们:

fun addMessageToDatabase(message: String, fromId: String, toId: String,
                                addedMessageSuccessHandler: () -> Unit,
                                addedMessageFailureHandler: () -> Unit) {



    val latestMessageRef = mDatabase.getReference("/latest-messages/$fromId/$toId")
    latestMessageRef.setValue(message).addOnSuccessListener {
        latestMessageUpdateSuccessHandler.invoke()

    }.addOnFailureListener {
        latestMessageUpdateFailureHandler.invoke()
    }
}

最后,您可以使用以下代码利用新的回调函数

databaseManager.updateLatestMessageForUsers(message, fromId, toId,
        latestMessageUpdateSuccessHandler = {
            // your success action
        },
        latestMessageUpdateFailureHandler = {
            // your failure action
        })

基本上,当我成功地向数据库添加新行时,我会向服务的调用者发出成功或失败的响应。希望这能帮助到某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接