Поместив файл JSON локально в папку src/main/assets
, вы можете легко получить доступ к его содержимому для его десериализации (здесь я использовал метод .decodeFromString()). Однако неясно, как десериализовать удаленные данные JSON в приложении Jetpack Compose.
Например, данные, расположенные по адресу https://api.opendota.com/api/heroStats
или по адресу https://restcountries.com/v3.1/all
.
Вот код с локальным анализом JSON:
@Serializable
data class Root(val tenants: List<Tenant>)
@Serializable
data class Tenant(val name: String, val room: Int)
@Composable
fun DecodedText() {
var text: String by remember { mutableStateOf("") }
val context = LocalContext.current
LaunchedEffect(Unit) {
val json = readJsonFromAssets(context = context, fileName = "sample.json")
val decoded = Json.decodeFromString<Root>(json).tenants
for (i in decoded.indices) {
text += decoded[i].name + " – "
text += decoded[i].room.toString() + "\n"
}
}
Text(
text = text,
fontWeight = FontWeight.Black,
fontSize = 22.sp,
modifier = Modifier.padding(50.dp)
)
}
fun readJsonFromAssets(context: Context, fileName: String): String {
return context.assets.open(fileName).bufferedReader().use { it.readText() }
}
Я хотел бы знать, как это сделать с помощью плагина сериализации Kotlin. Любая помощь приветствуется.
1. Вы не получаете файл по этому URL-адресу, вы получаете данные в формате JSON, в этом есть разница. 2. Вам нужно выбрать сетевую структуру, которую вы собираетесь использовать, поскольку каждая из них имеет свой собственный способ анализа данных json в объекты. Самым распространенным/популярным вариантом для Android является, вероятно, Retrofit, но есть и другие.
Внимательно изучив этот вопрос, я пришел к следующему решению. Я попытался проанализировать данные JSON, используя оба веб-адреса, оба примера декодируются нормально, для своего ответа я выбрал второй адрес. Вот мой код:
typealias Countries = List<Country>
private val jsonPty = Json {
ignoreUnknownKeys = true
}
@Serializable
data class Country(
val name: Names
)
@Serializable
data class Names(
val common: String,
val official: String
)
@ExperimentalSerializationApi
@Composable
fun RemoteDecodedText() {
val url = URL("https://restcountries.com/v3.1/all")
var json: String by remember { mutableStateOf("") }
var parsedJson: String by remember { mutableStateOf("") }
val scope = CoroutineScope(Dispatchers.Default)
LaunchedEffect(Unit) {
scope.launch {
json = url.openStream().use {
it.readAllBytes().decodeToString()
}
parsedJson = jsonPty.decodeFromString<Countries>(json)[64].name.official
}
}
Text(
text = "Location: $parsedJson",
fontSize = 20.sp,
fontWeight = FontWeight.Black,
modifier = Modifier.padding(60.dp)
)
}
Результат (индекс=64):
// Location: Kingdom of Morocco
Приятно знать, что Jetpack Compose — это инфраструктура пользовательского интерфейса, не предназначенная для такой логики. Обычно эта логика находится внутри Developer.android.com/topic/libraries/architecture/viewmodel . Там я бы рассмотрел анализ JSON с помощью Kotlin: stackoverflow.com/questions/41928803/…