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

如何从Kotlin协程中获取数据并赋值给变量?

协程异步数据赋值后无法立即读取的问题

我是一名初学者,抱歉问基础问题。我能轻松把协程里的数据输出到TextView这类View元素,但没法直接把数据存到变量里——除非先存到TextView再从里面取。

无法正常工作的代码

lateinit var bind: ActivityMainBinding
val scope = CoroutineScope(Dispatchers.Default)

var name2 = ""
var race2 = ""
var dexterity2 = ""
var wisdom2 = ""
var strength2 = ""

fun expData() {
    scope.launch {
        val apiData = URL(CHARACTER_DATA_API).readText()
        withContext(Dispatchers.Main) {
            var spl = apiData.split(",")
            
            Log.d("MyTag","spl:${spl}")
            
            name2 = spl[0]
            race2 = spl[1]
            dexterity2 = spl[2]
            wisdom2 = spl[3]
            strength2 = spl[4]
            
            Log.d("MyTag","spl val:${spl[0]},${spl[1]},${spl[2]},${spl[3]},${spl[4]}")
        }
    }
}

bind.butGenerate.setOnClickListener {
    expData()

    Log.d("MyTag","names var: ${name2},${race2},${dexterity2},${wisdom2},${strength2}")
}

日志输出

  1. spl:[halfling, Heavenly Baker, 15, 17, 7]
  2. spl val:halfling,Heavenly Baker,15,17,7
  3. names var:,,,,

我已经困扰两天了,找不到答案,恳请帮忙!(Т_Т)


可以正常工作但繁琐的代码

第一种直接赋值给View的写法:

lateinit var bind: ActivityMainBinding
val scope = CoroutineScope(Dispatchers.Default)

fun fetchCharacterData(bind: ActivityMainBinding){
    scope.launch {
        val apiData = URL(CHARACTER_DATA_API).readText()
        withContext(Dispatchers.Main) {
            val spl = apiData.split(",")
            bind.run {
                txtName.text = spl[0]
                txtRace.text = spl[1]
                txtDexterity.text = spl[2]
                txtWisdom.text = spl[3]
                txtStrength.text = spl[4]
            }
        }
    }
}

第二种先存到View再取的写法:

lateinit var bind: ActivityMainBinding
val scope = CoroutineScope(Dispatchers.Default)

fun fetchCharacterData(bind: ActivityMainBinding){
    scope.launch {
        val apiData = URL(CHARACTER_DATA_API).readText()
        withContext(Dispatchers.Main) {
            val spl = apiData.split(",")
            bind.run {
                txtName.text = spl[0]
                txtRace.text = spl[1]
                txtDexterity.text = spl[2]
                txtWisdom.text = spl[3]
                txtStrength.text = spl[4]
            }
        }
    }
}

val name = bind.txtName.text
val race = bind.txtRace.text
val dex = bind.txtDextirity.text
val wis = txtWisdom.text
val str = txtStrength.text

但我觉得这种方式太繁琐也不规范!


临时可行的代码(用循环等待)

lateinit var bind: ActivityMainBinding
val scope = CoroutineScope(Dispatchers.Default)

var name2 = ""
var race2 = ""
var dexterity2 = ""
var wisdom2 = ""
var strength2 = ""

fun expData() {
    scope.launch {
        val apiData = URL(CHARACTER_DATA_API).readText()
        withContext(Dispatchers.Main) {
            var spl = apiData.split(",")
            
            Log.d("MyTag","spl:${spl}")
            
            name2 = spl[0]
            race2 = spl[1]
            dexterity2 = spl[2]
            wisdom2 = spl[3]
            strength2 = spl[4]
            
            Log.d("MyTag","spl val:${spl[0]},${spl[1]},${spl[2]},${spl[3]},${spl[4]}")
        }
    }
}

bind.butGenerate.setOnClickListener {
    expData()
    scope.launch {
        withContext(Dispatchers.Main) {
            while (name2.isBlank()) {
                delay(20)
            }
            Log.d("MyTag","names var: ${name2},${race2},${dexterity2},${wisdom2},${strength2}")
        }
    }
}

请问正确的做法应该是什么?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:05:25