将回调代码迁移到暂停function
我正在使用协程将我的Android代码从Java重新分解到Kotlin,但是我没有find一种简单的方法来将基于回调的代码重写为挂起的函数。
一个基本的例子是一个警告popup框,返回一个结果,在Javascript中它将是这样的:
let value = prompt("please insert a value") console.log("Value:"+value)
我会在Kotlin翻译如下:
class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { //Standard activity initialization super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //Actual code... launch { val value = resolvable(UI) { success, error -> //Build a simple popup prompt with AlertDialog val input = EditText(this@MainActivity) val builder = AlertDialog.Builder(this@MainActivity) .setTitle("please insert a value") .setView(input) .setPositiveButton("Ok",{ dialog, id -> success(input.text.toString())//This lambda returns the value }) val dialog = builder.create() dialog.show() } println("Value:"+ value) } //... } }
可解析的是我为这个purpuse开发的一个自定义函数,这里是源代码:
import kotlinx.coroutines.experimental.DefaultDispatcher import kotlinx.coroutines.experimental.cancelAndJoin import kotlinx.coroutines.experimental.launch import java.util.concurrent.Semaphore import kotlin.coroutines.experimental.CoroutineContext suspend fun resolvable( context: CoroutineContext = DefaultDispatcher, block: suspend (success:(T?)->Unit,error:(Throwable)->Unit) -> Unit ):T?{ var result:T? = null var exception:Throwable? = null val semaphore = Semaphore(0) val job = launch(context){ block({r:T? -> { result=r semaphore.release() }},{e:Throwable -> { exception=e semaphore.release() }}) } semaphore.acquire() job.cancelAndJoin() if(exception!=null) throw exception!! return result }
我很快使用lambdas和信号量开发了可解析的函数(记住它是一个快速的草稿),但我不知道是否有任何预先存在的函数(我找不到任何函数)或可以优化或有任何缺点/问题。
谢谢。
看起来你正在试图重新suspendCoroutine
函数。 我建议用suspendCoroutine
调用来取代你的resolvable
函数,以获得你正在寻找的functiontypes:
//Actual code... launch(UI) { val value = suspendCoroutine { cont -> //Build a simple popup prompt with AlertDialog val input = EditText(this@MainActivity) val builder = AlertDialog.Builder(this@MainActivity) .setTitle("please insert a value") .setView(input) .setPositiveButton("Ok",{ dialog, id -> cont.resume(input.text.toString()) //!!! Resume here }) val dialog = builder.create() dialog.show() } println("Value:"+ value) }
如果在suspendCoroutine
块周围执行“提取函数”重构并命名产生的暂停函数prompt
,那么可以用与JS非常相似的样式编写代码。
你也可以考虑使用suspendCancellebleCoroutine
而不是简单的suspendCoroutine
。 这样,您可以支持取消启动的协程,并安装一个处理程序以在取消对话时关闭对话框。