如何使用Kotlin协程在API请求响应后更新TextView?
问题核心原因
你犯了ViewBinding使用的常见错误:
- 你已经通过
ActivityMainBinding.inflate(layoutInflater)生成了绑定实例b,但onCreate中setContentView传入的是布局IDR.layout.activity_main,而不是b.root - 这就导致你后续修改
b.gameTitle等控件的属性,操作的是绑定实例关联的独立视图,不是当前Activity实际渲染到屏幕上的视图,自然看不到任何变化
修复步骤
- 首先修改
onCreate里的setContentView代码:
把
setContentView(R.layout.activity_main)
替换为
setContentView(b.root)
- (可选优化)协程用法规范
不要自行创建CoroutineScope,Android官方提供了和Activity生命周期绑定的lifecycleScope,可以避免内存泄漏,修改listAllGames方法:
private fun listAllGames() { lifecycleScope.launch { // 网络请求切换到IO线程 val call = withContext(Dispatchers.IO) { getRetrofit().create(APIService::class.java).listAllGames("") } val games = call.body() // lifecycleScope默认在主线程运行,不需要额外调用runOnUiThread if (call.isSuccessful) { b.gameTitle.text = games?.get(0)?.title ?: "Dummy" b.gameDesc.text = games?.get(0)?.short_description ?: "Dummy" b.gameGenre.text = games?.get(0)?.genre ?: "Dummy" } else { Toast.makeText(applicationContext, "ERROR", Toast.LENGTH_SHORT).show() Log.d("mydebug", "call unsuccessful") } } }
使用lifecycleScope需要先引入依赖,在模块级build.gradle中添加:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
- (可选检查)Retrofit baseUrl配置
你当前的baseUrl是https://www.freetogame.com/api/games/,如果你的APIService中listAllGames方法的GET注解路径为空的话,最终请求地址是正确的;如果后续要扩展其他接口,建议把baseUrl改为https://www.freetogame.com/api/,listAllGames方法的GET注解改为@GET("games"),适配性更好。
内容的提问来源于stack exchange,提问作者xvlaze
相关产品推荐
相关产品推荐

