Jetpack Compose: Decoding JSON Elements using Kotlinx serialization

Introduction

Jetpack Compose, the modern toolkit for building native Android UIs, has brought a significant shift in how Android developers approach UI development, offering a declarative approach that streamlines the process of creating interactive applications. One of the key features often needed in Android applications is JSON serialization and deserialization, enabling apps to communicate seamlessly with remote data sources or local databases. Using Kotlin's kotlinx.serialization library, we can easily serialize and deserialize JSON data, making data handling in Compose applications both efficient and maintainable.

In this example, we'll explore how to create a basic Compose application that decodes a JSON element into a Kotlin data object using kotlinx.serialization. We’ll break down the code step-by-step, covering how to build a JSON object, decode it, and display the data in a Compose UI layout.

Code Breakdown

Setting up the Main Activity

The entry point of the application is the MainActivity class, which extends ComponentActivity. Inside onCreate, we use setContent to define our app's UI using Compose. The root theme for the application is provided by ComposeNetworkTheme, wrapping all UI components in a consistent design language.

Within the theme, the Scaffold composable organizes the layout of the app with a TopAppBar that contains a title reading "Serialization Decode JSON Element." This scaffold structure makes it easy to add consistent elements such as headers, content, and navigation bars, while keeping the code modular.

Creating the JSON Element

The core of this example lies in the MainContent composable, where we create and decode a JSON object. Here, we define a JsonObject using buildJsonObject. This method allows us to construct a JSON element on the fly by adding key-value pairs. We include fields for firstName, lastName, age, and dept, effectively simulating a simple user profile.

The created JSON object, stored in the variable element, resembles a typical JSON payload we might receive from an API or another data source. This JSON structure provides the necessary data, which we then decode into a Kotlin data class.

Decoding JSON with Kotlinx Serialization

Next, we use Json.decodeFromJsonElement<User>(element) to decode the JSON element into an instance of the User data class. The decodeFromJsonElement function is part of Kotlin's kotlinx.serialization library, specifically designed to work with JSON. By specifying <User> as the target type, we instruct the deserializer to map each JSON key to the corresponding property in the User class.

This decoding step is crucial for transforming JSON data into native Kotlin objects, enabling type-safe data handling throughout the application. Any JSON fields missing in the data class or incompatible types would result in a decoding error, which provides an added layer of data validation.

Displaying Decoded Data in the UI

The decoded user object is displayed in a simple Column layout within the MainContent composable. By calling user.toString(), we convert the user data into a readable format, which is then displayed as text using the Text composable. The text style is set to h6 from the Material typography, giving it a clear, readable appearance.

We wrap the Column with padding and use fillMaxSize() to ensure the layout takes up the available screen space, creating a centered, well-spaced UI. This concise UI design serves as a practical way to visualize deserialized data in Compose.

Defining the User Data Class

The User data class is annotated with @Serializable, making it compatible with the kotlinx.serialization library. Each property in the User class (firstName, lastName, age, and dept) corresponds to the keys in our JSON object. This class serves as the blueprint for our JSON decoding process, and by ensuring it’s Serializable, we enable both serialization and deserialization capabilities for instances of User.

Summary

This example demonstrates how to integrate JSON decoding into a Jetpack Compose application using Kotlin’s kotlinx.serialization library. Starting with the construction of a JSON object, we decode it into a data class instance and display the data in a simple Compose UI. By following this approach, developers can handle JSON data seamlessly within Compose, supporting dynamic and data-driven Android applications.

Using kotlinx.serialization with Jetpack Compose simplifies the process of converting JSON data into Kotlin objects, improving code readability and maintainability. This setup is ideal for modern Android applications that rely on structured data, making it easier to build responsive and data-rich interfaces.


MainActivity.kt

package com.cfsuman.composenetwork

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.cfsuman.composenetwork.ui.theme.ComposeNetworkTheme
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeNetworkTheme {
                Scaffold(
                    topBar = {
                        TopAppBar(
                            title = {
                                Text(
                                    "Serialization Decode Json Element"
                                )
                            }
                        )
                    },
                    content = { MainContent()}
                )
            }
        }
    }
}


@Composable
fun MainContent() {
    val element = buildJsonObject{
        put("firstName","Faria")
        put("lastName","Jones")
        put("age",23)
        put("dept","Management")
    }

    val user = Json.decodeFromJsonElement<User>(element)

    Column(Modifier.fillMaxSize().padding(24.dp)) {
        Text(
            text = user.toString(),
            style = MaterialTheme.typography.h6
        )
    }
}

@Serializable
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int,
    val dept: String
)
More android jetpack compose tutorials