【发布时间】:2019-04-20 00:45:08
【问题描述】:
这是我的界面:
interface BlogService {
suspend fun tag() : JsonObject
}
是否可以为suspend方法创建一个动态代理并在里面运行协程? 我无法使用 jdk 中的“Proxy.newProxyInstance”,因为我收到编译错误(应该从另一个挂起函数运行挂起函数)
【问题讨论】:
标签: kotlin
这是我的界面:
interface BlogService {
suspend fun tag() : JsonObject
}
是否可以为suspend方法创建一个动态代理并在里面运行协程? 我无法使用 jdk 中的“Proxy.newProxyInstance”,因为我收到编译错误(应该从另一个挂起函数运行挂起函数)
【问题讨论】:
标签: kotlin
我遇到了同样的问题。我认为答案是肯定的。这是我想出来的。
如下界面
interface IService {
suspend fun hello(arg: String): Int
}
编译成这个
interface IService {
fun hello(var1: String, var2: Continuation<Int>) : Any
}
编译后,普通函数和挂起没有区别
函数,除了后者有一个额外的类型参数
Continuation。只需在委托中返回COROUTINE_SUSPENDED
InvocationHandler.invoke 如果你真的想暂停它。
这是一个通过 java 动态代理创建 ISerivce 实例的示例
设施Proxy.newProxyInstance
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Proxy
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.resume
fun getServiceDynamic(): IService {
val proxy = InvocationHandler { _, method, args ->
val lastArg = args?.lastOrNull()
if (lastArg is Continuation<*>) {
val cont = lastArg as Continuation<Int>
val argsButLast = args.take(args.size - 1)
doSomethingWith(method, argsButLast, onComplete = { result: Int ->
cont.resume(result)
})
COROUTINE_SUSPENDED
} else {
0
}
}
return Proxy.newProxyInstance(
proxy.javaClass.classLoader,
arrayOf(IService::class.java),
proxy
) as IService
}
我相信这段代码 sn-p 足够简单且不言自明。
【讨论】: