Jetpack Compose - Kotlinx Serialization: Allow Special Floating Point Values

Introduction
In Android development, data serialization plays a crucial role in converting complex data structures into strings or other formats for easier storage or transmission. Kotlinx Serialization, a powerful library in the Kotlin ecosystem, provides extensive support for encoding and decoding various data types, making it highly valuable for modern Android applications. An interesting aspect of Kotlinx Serialization is its support for special floating-point values, such as NaN (Not-a-Number) and infinity, which may arise in applications dealing with calculations or unique data conditions.

In this article, we'll explore an example that demonstrates how to enable special floating-point values in Kotlinx Serialization within a Jetpack Compose app. This feature can be particularly useful when handling uncommon data scenarios, allowing your app to remain robust and flexible. We’ll break down each part of the example, starting from setting up the main activity to configuring Kotlinx Serialization to support special floating-point values.

MainActivity Setup
The code begins with the MainActivity class, which serves as the entry point of the app. Extending ComponentActivity, it overrides the onCreate function, where we define the app's primary user interface. Using Jetpack Compose’s setContent function, we initiate the content layout for the activity. The ComposeNetworkTheme wrapper is applied to maintain a consistent theme throughout the app, giving it a cohesive look and feel.

Inside the layout, a Scaffold component is used to provide structure to the app, which includes a TopAppBar at the top of the screen. The app bar displays a title, "Serialization Allow Special Floating Point Values," set to a single line with ellipsis in case of overflow. The Scaffold structure is beneficial in Android apps as it organizes UI components and ensures that essential elements like the app bar are available across screens.

Composable Function: MainContent
The core functionality of the app resides in the MainContent composable function. This function creates an instance of Json with specific configuration settings to allow special floating-point values. This configuration is essential for enabling the allowSpecialFloatingPointValues flag, which supports values like NaN (Not-a-Number), positive infinity, and negative infinity. Setting this flag to true is critical when dealing with data that might contain these special floating-point values, as it prevents serialization errors and ensures data integrity.

Within MainContent, we define a Product data object with the name "School Bag" and a price set to Double.NaN, simulating a case where a special floating-point value (NaN) is used. By calling format.encodeToString(product), the Product object is serialized into a JSON string, with prettyPrint enabled for better readability. This JSON string is then displayed in the UI as a formatted Text composable, which shows the serialized output with special floating-point handling enabled.

Data Class: Product
The Product data class is a straightforward representation of an item with two properties: name and price. The @Serializable annotation marks the data class for use with Kotlinx Serialization, enabling it to be converted to and from JSON. The price property is defined as a Double, allowing it to accept both regular numeric values and special floating-point values, like NaN and infinity. This flexibility is crucial for applications that might encounter irregular data, providing a resilient way to handle such values without crashing or throwing errors during serialization.

By using the @Serializable annotation, the app can seamlessly integrate with the serialization library, converting the Product object into a JSON-compatible string. This functionality illustrates the versatility of Kotlinx Serialization, making it ideal for handling various data types in Android applications.

Summary
This example highlights how Kotlinx Serialization’s support for special floating-point values can be used effectively in an Android app built with Jetpack Compose. By enabling the allowSpecialFloatingPointValues flag, developers can handle values like NaN gracefully, which might appear in datasets or calculations, without risking serialization failures. This capability is especially useful in applications that process complex mathematical data or deal with unusual data states.

Overall, Kotlinx Serialization, combined with Jetpack Compose, provides Android developers with a robust toolset for managing data representation and display. As shown in this example, handling special floating-point values not only strengthens the app’s resilience but also enhances its flexibility, making Kotlinx Serialization a valuable library for modern Android development.


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.text.style.TextOverflow
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.Json


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeNetworkTheme {
                Scaffold(
                    topBar = {
                        TopAppBar(
                            title = {
                                Text(
                                    text = "Serialization Allow Special" +
                                            " Floating Point Values",
                                    maxLines = 1,
                                    overflow = TextOverflow.Ellipsis
                                )
                            }
                        )
                    },
                    content = { MainContent()}
                )
            }
        }
    }
}


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

    val product = Product(name = "School Bag", price = Double.NaN)
    val productString = format.encodeToString(product)

    Column(Modifier.fillMaxSize().padding(24.dp)) {
        Text(
            text = productString,
            style = MaterialTheme.typography.h5
        )
    }
}


@Serializable
data class Product(
    val name: String,
    val price: Double
)
More android jetpack compose tutorials