Kotlin常用操作记录

/ 0评 / 1

使用协程封装异步操作

private suspend fun showDialog(context: Activity): Boolean {
    return suspendCoroutine {
        val builder = AlertDialog.Builder(context)
        builder.setTitle("问题:")
        builder.setMessage("请问你满十八岁了吗?")
        builder.setIcon(R.mipmap.ic_launcher_round)
        builder.setCancelable(true)
        builder.setPositiveButton("是的") { dialog, which ->
            dialog.dismiss()
            it.resume(true)
        }
        builder.setNegativeButton("不是") { dialog, which ->
            dialog.dismiss()
            it.resume(false)
        }
        builder.show()
    }
}

如上所示,我们使用suspendCoroutine将异步的弹窗显示转换为同步的显示,只需要如下使用,则可以同步获取结果

launch {
    val result = showDialog(this@MainActivity)
    Toast.makeText(this@MainActivity, "result = ${result}", Toast.LENGTH_SHORT).show()
}

当然也可以抛出异常或者使用Result

it.resumeWithException(Exception()) //抛出异常
it.resumeWith(Result.success(false))//返回Result对象
it.resumeWith(Result.failure(Exception("")))//抛出异常

还有一个suspendCancellableCoroutine,与suspendCoroutine的区别为提供了一个cancel方法

private suspend fun showDialog(context: Activity): Boolean {
    return suspendCancellableCoroutine {
        val builder = AlertDialog.Builder(context)
        builder.setTitle("问题:")
        builder.setMessage("请问你满十八岁了吗?")
        builder.setIcon(R.mipmap.ic_launcher_round)
        builder.setCancelable(true)
        builder.setPositiveButton("是的") { dialog, which ->
            dialog.dismiss()
            it.resume(true)
        }
        builder.setNegativeButton("不是") { dialog, which ->
            dialog.dismiss()
            //如果不传递,默认也是CancellationException,或者抛出其他异常
            it.cancel(CancellationException("2333"))
        }
        builder.show()
    }
}

协程异常处理

val handler = CoroutineExceptionHandler { _, exception ->
    println("CoroutineExceptionHandler got $exception")
}
launch(handler){

}

Android中能使用的CoroutineScope

class MainActivity : AppCompatActivity() {

    private val scope = MainScope()

    override fun onDestroy() {
        super.onDestroy()
        scope.cancel()
    }
}

倒计时

fun countDownCoroutines(
    total: Int, onTick: (Int) -> Unit, 
    onFinish: () -> Unit,
    scope: CoroutineScope = GlobalScope
): Job {
    return flow {
        for (i in total downTo 0) {
            emit(i)
            delay(1000)
        }
    }.flowOn(Dispatchers.Default)
        .onCompletion {
            if (it == null) onFinish()
        }
        .onEach { onTick(it) }
        .flowOn(Dispatchers.Main)
        .launchIn(scope)
}

超时

//会抛出TimeoutCancellationException,导致协程被取消
withTimeout(1300L) {
    val startTime = System.currentTimeMillis()
    repeat(1000) { i ->
        println("[job] 运行: $i, 累积运行时间: ${System.currentTimeMillis() - startTime}毫秒")
        delay(5000L)
    }
}

//这一个不会抛出异常,会返回null
withTimeoutOrNull(1300L) {
    val startTime = System.currentTimeMillis()
    repeat(1000) { i ->
        println("[job] 运行: $i, 累积运行时间: ${System.currentTimeMillis() - startTime}毫秒")
        delay(5000L)
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注