Jetpack Compose: Kotlinx serialization decode from string

Introduction

In the world of Android app development, handling structured data formats like JSON is crucial for interacting with APIs and managing data in a readable, transportable format. Jetpack Compose and Kotlin’s kotlinx.serialization library make it easier than ever to integrate and display JSON data in Android applications. This example demonstrates how to use Jetpack Compose alongside Kotlin’s serialization library to decode JSON data from a string and render it dynamically within a simple Android UI. By focusing on Kotlin’s robust serialization tools and Jetpack Compose’s declarative UI, developers can simplify their data-handling workflows and create reactive, data-driven user interfaces.

In this article, we will walk through the provided code for an Android application in Kotlin, which decodes a JSON string representing an employee profile and displays it in a Compose layout. We’ll break down each section of the code, highlighting key concepts such as JSON deserialization with kotlinx.serialization and layout building with Jetpack Compose. By the end, you'll have a clear understanding of how to leverage these libraries to decode JSON data directly into Kotlin objects and display them in an Android UI.

Code Breakdown: MainActivity.kt Setup

The code begins with the MainActivity class, which serves as the entry point of the app and extends ComponentActivity. Inside the onCreate function, the setContent block is used to set the UI content of the activity using Jetpack Compose’s ComposeNetworkTheme for consistent theming. Here, the Scaffold component is employed to create a structured layout, with a TopAppBar serving as the header and the MainContent composable function as the main display area. This setup forms the foundation of the app's layout and utilizes Compose's theme and scaffolding patterns to maintain a clear structure.

The TopAppBar component displays a title, "Serialization Decode From String," which indicates the app’s primary function. Jetpack Compose's top-level scaffolding component, Scaffold, ensures a flexible structure, making it easy to add more composable functions or elements later if necessary.

JSON Decoding with Kotlinx Serialization

Inside the MainContent composable, we initialize a JSON format configuration using the Json class. The configuration option isLenient = true allows for more flexibility in JSON parsing, making it tolerant of non-standard formatting in the JSON string. This setup makes the decoding process more resilient, accommodating JSON strings that may not follow strict standards, which can be especially useful when handling data from external sources.

An employee's data in JSON format is then stored in a variable called employeeJsonString. This string contains basic information about the employee, including first name, last name, department, salary, and age. Using the decodeFromString function, the JSON string is deserialized into an instance of the Employee data class, which is annotated with @Serializable to enable serialization and deserialization. This process directly maps JSON fields to Kotlin properties, allowing seamless conversion from JSON data into Kotlin objects.

Displaying Deserialized Data in the UI

The deserialized Employee object is then displayed within a Column composable layout, which stacks its child composables vertically. Inside the Column, a Text composable is used to display the employee’s details, including their name, department, salary, and age. The use of MaterialTheme.typography.h5 sets the text styling, providing a consistent look and feel in line with Material Design guidelines. This approach leverages Compose's declarative syntax, making it straightforward to dynamically display the data based on the properties of the Employee object.

Additionally, the Modifier.fillMaxSize().padding(24.dp) applied to the Column composable ensures that the content fills the available space and has consistent padding. This layout approach not only simplifies the structure but also ensures that the UI adapts to different screen sizes while keeping the content neatly organized.

Employee Data Class Definition

At the bottom of the code, the Employee data class defines the structure of the employee object. Each property in the class (e.g., firstName, lastName, dept, salary, age) corresponds to a field in the JSON string. The @Serializable annotation is essential here, as it enables the Employee class to be serialized and deserialized by the kotlinx.serialization library. This class acts as the blueprint for any employee-related data that the app might handle, ensuring a clear and reusable data structure that simplifies future expansions or modifications.

Summary

In summary, this example showcases how to decode JSON data using Kotlin's kotlinx.serialization library and display it in an Android app built with Jetpack Compose. By using @Serializable data classes and setting up a flexible Json configuration, developers can easily handle JSON strings and convert them to structured Kotlin objects. The use of Jetpack Compose’s declarative UI approach makes displaying this data straightforward, clean, and responsive to changes.

This example highlights the synergy between Jetpack Compose and Kotlin’s serialization capabilities, demonstrating how a data-driven Android UI can be constructed efficiently. With minimal code, developers can create apps that handle JSON data smoothly, making this approach ideal for applications that interact with APIs or handle dynamic data inputs.


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.decodeFromString
import kotlinx.serialization.json.Json


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


@Composable
fun MainContent() {
    val format = Json{
        isLenient = true
    }

    val employeeJsonString = "{ firstName: Jenny, lastName: Jones," +
            "dept: Accounting, salary:1200, age:28}"

    val employee = format.decodeFromString<Employee>(employeeJsonString)

    Column(Modifier.fillMaxSize().padding(24.dp)) {
        Text(
            text = "${employee.firstName} ${employee.lastName}" +
                    "\nDepartment: ${employee.dept}" +
                    "\nSalary: ${employee.salary} USD" +
                    "\nAge: ${employee.age}",
            style = MaterialTheme.typography.h5
        )
    }
}


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