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

如何在Kotlin协程外部获取协程内部生成的变量值

问题根源

你碰到的不是变量跨作用域传值的问题,是异步代码执行顺序不对:

  • Firestore的get()是异步网络请求,addOnCompleteListener回调、你自己开的IO协程里的逻辑,都不会阻塞外层onMapReady的执行
  • 你写在协程外面的addMarker、moveCamera会在网络请求还没返回、loc变量还没生成的时候就直接执行,就算你在外层声明个可变变量等协程里赋值,这两行操作地图的代码拿到的也只会是初始的硬编码值,根本等不到异步结果。
最简实现方案

不用搞复杂的接口回调、LiveData之类的东西,直接把依赖坐标的地图操作挪到协程里拿到结果之后执行就行,注意操作UI必须切主线程,优化后的代码如下:

override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap
    val routenuebergabe = intent.getStringExtra("tourname").toString()

    // 用页面生命周期绑定的lifecycleScope开协程,页面销毁自动取消任务,避免内存泄漏
    lifecycleScope.launch {
        // 先给个默认兜底坐标
        var startlocation = LatLng(49.7913, 9.9534)
        try {
            // Firestore KTX库自带await()挂起函数,不需要额外套addOnCompleteListener回调
            val doc = Firebase.firestore.collection("Routen")
                .document(routenuebergabe)
                .get()
                .await()

            val koors = doc.get("starting_location").toString()
            val strs = koors.split(",").toTypedArray()
            val lat = strs[0].toDouble()
            val lng = strs[1].toDouble()
            startlocation = LatLng(lat, lng)
            Log.e("RoutendarstellungActivity", "Fatal $lat & $lng")
        } catch (e: Exception) {
            // 请求失败、格式解析错误就用默认坐标
            e.printStackTrace()
        }

        // 切主线程操作地图
        withContext(Dispatchers.Main) {
            mMap.addMarker(MarkerOptions().position(startlocation).title("Marker in Würzburg"))
            mMap.moveCamera(CameraUpdateFactory.newLatLng(startlocation))
        }
    }
}
几个要注意的点
  • 不要手动创建CoroutineScope(Dispatchers.IO)这种无绑定的协程,在Activity里优先用lifecycleScope,不会出现页面退了之后协程还在跑、空指针崩溃的问题
  • 挂起函数(比如这里Firebase的await())会自动等待异步任务返回,不会卡主线程,写起来和同步代码逻辑一致,不需要嵌套多层回调
  • 网络请求、数据解析都要加异常捕获,失败的时候走兜底逻辑,避免APP直接崩溃

内容的提问来源于stack exchange,提问作者Featch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:48:14