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

Jetpack Compose如何将onResponse回调中解析的JSON数据显示到Text Composable

实现方案

核心逻辑是通过Compose可观察状态驱动UI更新,同时处理线程切换和避免重复请求,具体实现如下:

核心修正点

  • Compose为响应式UI框架,只有可观察状态发生变更时才会触发UI重组更新,需要用mutableStateListOf/mutableStateOf存储请求到的数据
  • OkHttp异步回调运行在子线程,高版本Compose已支持子线程直接更新状态,无需额外切换主线程
  • 不能直接在Composable顶层执行网络请求,否则每次页面重组都会重复发起请求,需要用LaunchedEffect包裹保证仅首次初始化时执行一次

完整实现代码

import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import okhttp3.*
import java.io.IOException

// 原有数据类无需修改
data class Json(
    @field:SerializedName("title")
    val title: String? = null,
)

@Composable
fun ApiScreen() {
    // 定义可观察的标题列表状态,数据变更自动触发UI更新
    val titleList = remember { mutableStateListOf<String>() }
    // 可选:定义错误状态,用于请求失败提示
    val errorMsg = remember { mutableStateOf<String?>(null) }

    // 网络请求包裹在LaunchedEffect中,key为Unit时仅页面首次加载时执行一次
    LaunchedEffect(Unit) {
        val url = "https://jsonplaceholder.typicode.com/posts"
        val request = Request.Builder().url(url).build()
        val client = OkHttpClient()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                errorMsg.value = "请求失败:${e.message}"
            }

            override fun onResponse(call: Call, response: Response) {
                response.body()?.string()?.let { body ->
                    val bundle = Gson().fromJson(body, Array<Json>::class.java)
                    // 提取所有非空标题
                    val titles = bundle.mapNotNull { it.title }
                    // 更新状态触发UI重组
                    titleList.addAll(titles)
                }
            }
        })
    }

    // UI渲染逻辑
    errorMsg.value?.let {
        Text(text = it)
    } ?: run {
        // 多条数据用LazyColumn滚动展示
        LazyColumn {
            items(titleList) { title ->
                Text(text = title)
            }
        }
    }
}

优化建议

  • 正式项目推荐将网络请求逻辑、状态存储放在ViewModel中,可避免配置变更(如屏幕旋转)导致的重复请求问题
  • 可新增加载状态,请求过程中展示CircularProgressIndicator加载提示,优化用户体验
  • 推荐用Retrofit封装网络请求,无需手动处理OkHttp回调、JSON解析流程,代码可维护性更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 08:42:03