Kotlin高阶函数传递一个带有可变数量参数的函数作为参数

时间:2018-01-18 08:56:42

标签: android multithreading kotlin higher-order-functions

在我的应用程序中,我需要使用特定框架执行网络调用。 因为每个网络调用都需要在单独的线程上执行,所以我希望有一个函数启动新线程执行调用并返回一个对象。 为此,我尝试使用HigherOrderFunctions,但直到现在我才发现如何将函数声明为一个带有可变数量参数的参数。

为了给你一个想法,我希望有这样的东西:

    fun  Client.performNetworkCall(calledFunction:(vararg Object)->Object):Object{
Thread(Runnable {
  calledFunction
}).start()

 //return function results

}

但似乎无法宣布这样的功能。 在Kotlin有可能吗? 当我需要执行网络调用时,我想避免在代码中每次创建新线程。所以我可以写这样的东西

client.performNetworkCall{ bean.createNewUser(User("","","Gosia","gosiak@gmail.com","pass"))}

bean是我的接口的对象,它有一个函数createNewUser。函数createNewUser在服务器上实现,并在执行后返回一些结果。

如果使用高阶函数无法实现我想做的事情,你能否给我一个提示,我还能做些什么,如上所述?

1 个答案:

答案 0 :(得分:2)

无论您提出什么要求都违反Android最佳做法。可能是你错误地提到了它。您希望函数在后台线程中执行高阶函数并且(请注意这里)立即返回值(意味着阻止调用线程直到后台任务完成)。

因为您必须知道网络调用应该是异步调用,因此您必须将接口作为参数传递给async方法,以便在高阶函数完成时通知您执行。

更好的选择是使用Coroutines作为后台调度任务的一个非常好的替代方案。

因此您的代码可以转换为:

async {
    var result = bean.createNewUser(User("","","Gosia","gosiak@gmail.com","pass"))
    // do whatever you want to do with result here        
}

使用Coroutines,您必须在模块级gradle文件中添加以下行:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21.2'

注意:协同程序现在处于试验阶段,可能会发生变化。

使用kotlin anko 库中的 doAsync 的另一个选项非常简单易用。

示例:

doAsync {
        var result = bean.createNewUser(User("","","Gosia","gosiak@gmail.com","pass"))
        // use result here to to further background task

        uiThread {
            // use result here if you want to update ui
        }
    }

使用 doAsync 在模块级gradle文件中添加以下行:

compile "org.jetbrains.anko:anko-commons:0.10.0"

要了解有关doAsync的更多信息,请点击here

希望它有所帮助。如果您还有其他问题,请与我们联系。