Android Kotlin中是否有方法等待获取MaterialAlertDialogBuilder的返回值?
基于Kotlin协程实现等待AlertDialog用户输入的最佳实践
对于将回调式API转为同步调用风格的需求,Kotlin协程官方推荐使用
suspendCancellableCoroutine桥接回调,既可以实现等待用户操作返回结果再执行后续代码的需求,也符合Android协程的最佳实践。
注意事项
- 不要使用
GlobalScope启动协程,推荐使用和页面生命周期绑定的lifecycleScope(Activity/Fragment场景)或者viewModelScope(ViewModel场景),避免对话框未关闭时页面销毁导致的内存泄漏 - 封装后的挂起函数必须在协程作用域内调用
实现代码
1. 封装对话框挂起函数
import kotlinx.coroutines.suspendCancellableCoroutine import kotlin.coroutines.resume // 封装成挂起函数,返回用户输入的字符串,点取消/关闭对话框返回null suspend fun showInputNameDialog(context: Context): String? = suspendCancellableCoroutine { continuation -> val customAlertDialogView = LayoutInflater.from(context) .inflate(R.layout.dialod_input_et, null, false) val inputNameEt = customAlertDialogView.findViewById<EditText>(R.id.input_dialog_et) val dialog = MaterialAlertDialogBuilder(context) .setView(customAlertDialogView) .setTitle("Type the name") .setPositiveButton("Accept", null) // 先设置空点击,后续自定义逻辑避免空输入自动关闭对话框 .setNegativeButton("Cancel") { _, _ -> if (continuation.isActive) { continuation.resume(null) } } .setOnDismissListener { if (continuation.isActive) { continuation.resume(null) } } .create() // 自定义确认按钮点击逻辑 dialog.setOnShowListener { dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { val inputContent = inputNameEt.text.toString().trim() if (inputContent.isEmpty()) { Toast.makeText(context, "Type a name", Toast.LENGTH_SHORT).show() return@setOnClickListener } if (continuation.isActive) { continuation.resume(inputContent) } dialog.dismiss() } } // 协程取消时自动关闭对话框 continuation.invokeOnCancellation { dialog.dismiss() } dialog.show() }
2. 调用示例(Fragment场景)
// 比如在按钮点击事件中触发 lifecycleScope.launch { // 此处会挂起,直到用户操作对话框返回结果后才会执行后续代码 val inputName = showInputNameDialog(requireContext()) // 用户点击取消/关闭对话框时直接终止后续逻辑 inputName ?: return@launch // 拿到输入结果后的后续业务逻辑 nameToDisplay = inputName // 其他业务代码... }
原有代码问题说明
你之前的实现没有生效,主要有两个原因:
- 你使用
GlobalScope.launch启动了顶层协程,没有在当前执行流程中等待async的返回结果,代码在调用show()之后直接继续执行,自然拿不到异步返回的输入值 GlobalScope没有和页面生命周期绑定,如果对话框还没关闭页面就被销毁,会导致内存泄漏
内容的提问来源于stack exchange,提问作者madbeans
相关产品推荐
相关产品推荐

