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
相关产品推荐
相关产品推荐

