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

如何在Jetpack Compose应用中读取并解析远程JSON数据?

在Jetpack Compose中使用Kotlin Serialization解析远程JSON数据

要实现远程JSON数据的解析,核心步骤是发起网络请求获取JSON字符串,再用Kotlin Serialization进行反序列化,以下是具体实现方案:

1. 添加必要依赖

首先在Module级别的build.gradle.kts中添加网络请求和序列化相关依赖:

plugins {
    kotlin("plugin.serialization") version "1.9.20" // 版本需与项目Kotlin版本匹配
}

dependencies {
    // Kotlin Serialization核心库
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
    // 网络请求依赖(以Retrofit为例,更推荐封装式请求)
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
}

同时在AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

2. 定义对应API的数据模型

根据目标接口的JSON结构,创建可序列化的数据类,以https://restcountries.com/v3.1/all为例:

@Serializable
data class Country(
    val name: CountryName,
    val capital: List<String>? = null,
    val region: String
)

@Serializable
data class CountryName(
    val common: String,
    val official: String
)

若JSON字段较多,可添加Json { ignoreUnknownKeys = true }配置,忽略未定义的字段避免解析失败。

3. 实现网络请求与解析

方式一:Retrofit封装请求(推荐)

Retrofit会自动完成请求与序列化的绑定:

// 定义API接口
interface CountriesApi {
    @GET("v3.1/all")
    suspend fun getAllCountries(): List<Country>
}

// 创建Retrofit实例
fun createCountriesApi(): CountriesApi {
    val jsonConfig = Json { ignoreUnknownKeys = true }
    return Retrofit.Builder()
        .baseUrl("https://restcountries.com/")
        .addConverterFactory(jsonConfig.asConverterFactory("application/json".toMediaType()))
        .build()
        .create(CountriesApi::class.java)
}

// 在Composable中使用
@Composable
fun RetrofitRemoteParser() {
    var countries: List<Country> by remember { mutableStateOf(emptyList()) }
    var errorMsg: String? by remember { mutableStateOf(null) }
    val api = remember { createCountriesApi() }

    LaunchedEffect(Unit) {
        try {
            countries = api.getAllCountries()
        } catch (e: Exception) {
            errorMsg = e.localizedMessage
        }
    }

    Column(modifier = Modifier.padding(20.dp)) {
        errorMsg?.let {
            Text(text = "请求失败:$it", color = Color.Red)
        } ?: run {
            LazyColumn {
                items(countries) { country ->
                    Text(
                        text = "${country.name.common} | 首都:${country.capital?.firstOrNull() ?: "无"}",
                        fontSize = 18.sp,
                        modifier = Modifier.padding(vertical = 8.dp)
                    )
                }
            }
        }
    }
}

方式二:OkHttp直接发起请求

若不需要Retrofit的封装,可直接用OkHttp获取JSON字符串后手动解析:

// 网络请求工具函数
suspend fun fetchRemoteJson(url: String): String {
    val client = OkHttpClient()
    val request = Request.Builder().url(url).build()
    return client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("请求错误:${response.code}")
        response.body?.string() ?: throw IOException("响应体为空")
    }
}

// 在Composable中使用
@Composable
fun OkHttpRemoteParser() {
    var countries: List<Country> by remember { mutableStateOf(emptyList()) }
    var errorMsg: String? by remember { mutableStateOf(null) }

    LaunchedEffect(Unit) {
        try {
            val jsonStr = fetchRemoteJson("https://restcountries.com/v3.1/all")
            countries = Json.decodeFromString(jsonStr)
        } catch (e: Exception) {
            errorMsg = e.localizedMessage
        }
    }

    // 后续UI渲染逻辑同Retrofit示例
}

关键注意事项

  • 网络请求必须在协程中执行,LaunchedEffect是Composable中发起协程的常用方式,也可结合ViewModel的viewModelScope实现更稳定的状态管理
  • 务必处理网络异常和解析异常,避免应用崩溃
  • 若接口需要请求头(如API密钥),可在Retrofit或OkHttp中添加对应配置

内容的提问来源于stack exchange,提问作者dàhóngpāo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:04:57