You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin的Method Channel中实现回调/协程以异步返回数据

实现方案

核心思路是暂存Method Channel返回的Result对象,等目标回调触发、数据准备完成后再调用该对象的返回方法将数据传回Flutter端,具体实现步骤如下:

1. 先声明必要的全局成员变量

// 暂存Method Channel的返回对象
private var pendingResult: MethodChannel.Result? = null
// 登录状态标记
private var userLogged = false
// 待返回的数据集
private val list: MutableList<String> = ArrayList()
// 定义Channel常量,替换为你实际的Channel名
private val CHANNEL = "自定义channel名称"

2. 改造MethodCallHandler的登录逻辑

不要在loginChannel被调用时当场返回数据,仅暂存Result对象并触发你的登录/数据获取流程即可:

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine);
    super.configureFlutterEngine(flutterEngine)

    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        .setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
            when(call.method) {
                "createChannel" -> {
                    // 你的原有逻辑
                }
                "loginChannel" -> {
                    if (!userLogged) {
                        // 暂存返回对象,不要当场调用success
                        pendingResult = result
                        // 触发你的登录/数据获取流程,比如调用第三方登录接口、异步任务
                        startLoginAction()
                    } else {
                        // 如果已经登录/数据已就绪可以直接返回
                        result.success(list.toString())
                    }
                }
                else -> result.notImplemented()
            }
        }
}

3. 在数据准备完成的回调中触发返回

在你提到的另一个触发函数(比如登录成功回调、异步数据获取完成回调)中,调用之前暂存的pendingResult返回数据即可:

// 这就是你说的另一个触发函数,比如登录成功的回调
private fun onDataReady() {
    userLogged = true
    // 这里可以给list赋值你要返回的最新数据
    // list.add("返回数据1")
    // list.add("返回数据2")
    
    // 必须切主线程调用Result的返回方法,避免子线程调用报错
    runOnUiThread {
        // 返回数据给Flutter端
        pendingResult?.success(list.toString())
        Toast.makeText(this, list.toString(), Toast.LENGTH_LONG).show()
        // 用完必须置空,避免重复调用Result抛异常
        pendingResult = null
    }
}

// 可选:流程出错的情况也要处理,返回错误信息后同样置空pendingResult
private fun onActionError(errorMsg: String) {
    runOnUiThread {
        pendingResult?.error("ACTION_ERROR", errorMsg, null)
        pendingResult = null
    }
}

注意事项

  • MethodChannel.Result的success/error/notImplemented方法只能调用一次,调用完成后必须将暂存的pendingResult置空,否则二次调用会直接崩溃
  • 必须在Android主线程调用Result的返回方法,如果你的回调运行在子线程,务必通过runOnUiThread切换线程
  • 如果页面销毁时还未触发回调,要手动将pendingResult置空,避免内存泄漏

内容的提问来源于stack exchange,提问作者Jakub Kořenek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:06:07