JSON (JavaScript Object Notation) is the standard data format for REST APIs. Android apps receive JSON as text and must parse it into Kotlin objects to display in the UI or store locally.
API Response (JSON String)
↓
Parsing / Deserialization
↓
Kotlin Data Classes
↓
UI (RecyclerView, TextView, etc.)
JSON Type
Kotlin Type
Example
Object { }
data class
{"name": "Nikhil"}
Array [ ]
List<T>
[1, 2, 3]
String
String
"hello"
Number
Int / Double
42, 3.14
Boolean
Boolean
true
null
nullable type
null
1JSON Objects
A JSON object is a collection of key-value pairs wrapped in curly braces { }. Keys are always strings; values can be strings, numbers, booleans, null, arrays, or nested objects.
Kotlin — Nested data classesdata class User(
val id: Int,
val name: String,
val address: Address
)
data class Address(
val street: String,
val city: String,
val zipCode: String
)
Access with org.json.JSONObject
Kotlin — Read object fields manuallyval jsonString = """{"id":1,"name":"Nikhil","email":"nikhil@example.com"}"""
val jsonObject = JSONObject(jsonString)
val id = jsonObject.getInt("id")
val name = jsonObject.getString("name")
val email = jsonObject.optString("email", "") // safe — returns default if missing
// Nested object
val addressObj = jsonObject.getJSONObject("address")
val city = addressObj.getString("city")
2JSON Arrays
A JSON array is an ordered list of values wrapped in square brackets [ ]. Arrays commonly hold lists of objects — such as posts, users, or products from an API.
Kotlin — List of data classdata class Post(
val id: Int,
val title: String,
val body: String
)
// Type: List<Post>
Access with org.json.JSONArray
Kotlin — Loop through JSONArrayval jsonArray = JSONArray(jsonString)
val posts = mutableListOf<Post>()
for (i in 0 until jsonArray.length()) {
val obj = jsonArray.getJSONObject(i)
posts.add(
Post(
id = obj.getInt("id"),
title = obj.getString("title"),
body = obj.getString("body")
)
)
}
Parsing JSON means reading a JSON string and extracting structured data. Android provides built-in org.json classes, or you can use libraries like Gson for automatic mapping.
Manual parsing — complete example
Kotlin — JsonParser.ktobject JsonParser {
fun parseUser(jsonString: String): User? {
return try {
val obj = JSONObject(jsonString)
User(
id = obj.getInt("id"),
name = obj.getString("name"),
email = obj.getString("email"),
isActive = obj.optBoolean("isActive", true),
avatarUrl = obj.optString("avatarUrl").ifEmpty { null }
)
} catch (e: JSONException) {
Log.e("JsonParser", "Failed to parse user", e)
null
}
}
fun parsePostList(jsonString: String): List<Post> {
val posts = mutableListOf<Post>()
try {
val array = JSONArray(jsonString)
for (i in 0 until array.length()) {
val obj = array.getJSONObject(i)
posts.add(
Post(
id = obj.getInt("id"),
title = obj.getString("title"),
body = obj.getString("body")
)
)
}
} catch (e: JSONException) {
Log.e("JsonParser", "Failed to parse posts", e)
}
return posts
}
fun parseApiResponse(jsonString: String): ApiResponse? {
return try {
val root = JSONObject(jsonString)
val dataArray = root.getJSONArray("data")
val items = mutableListOf<Item>()
for (i in 0 until dataArray.length()) {
val obj = dataArray.getJSONObject(i)
items.add(Item(id = obj.getInt("id"), name = obj.getString("name")))
}
ApiResponse(
status = root.getString("status"),
count = root.getInt("count"),
data = items
)
} catch (e: JSONException) {
null
}
}
}
data class ApiResponse(val status: String, val count: Int, val data: List<Item>)
data class Item(val id: Int, val name: String)
Parse from assets or raw resource
Kotlin — Read JSON from assetsfun Context.readJsonFromAssets(fileName: String): String {
return assets.open(fileName).bufferedReader().use { it.readText() }
}
// Usage in Activity:
val jsonString = readJsonFromAssets("posts.json")
val posts = JsonParser.parsePostList(jsonString)
When to parse manually vs use a library
Approach
Best For
org.json (manual)
Simple objects, learning, no extra dependency
Gson / Moshi
Complex models, Retrofit integration, production apps
4Gson Library
Gson is Google's library for converting between JSON and Kotlin/Java objects. It is widely used with Retrofit and removes the need for manual JSONObject/JSONArray loops.
Kotlin — GsonHelper.ktobject GsonHelper {
private val gson = Gson()
fun fromJson(json: String): User {
return gson.fromJson(json, User::class.java)
}
fun fromJsonList(json: String): List<Post> {
val type = object : TypeToken<List<Post>>() {}.type
return gson.fromJson(json, type)
}
fun toJson(user: User): String {
return gson.toJson(user)
}
}
Field name mapping with @SerializedName
Kotlin — Map snake_case JSON to camelCasedata class Product(
val id: Int,
val name: String,
@SerializedName("unit_price") val unitPrice: Double,
@SerializedName("in_stock") val inStock: Boolean
)
// JSON: {"id":1,"name":"Phone","unit_price":999.99,"in_stock":true}
Custom Gson instance with options
Kotlin — GsonBuilder configurationval gson = GsonBuilder()
.setLenient() // allow malformed JSON
.serializeNulls() // include null fields in output
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss") // parse date strings
.create()
Deserialization converts JSON → Kotlin object (reading/parsing). Serialization converts Kotlin object → JSON string (writing/saving). Both directions are essential for API calls and local caching.
Deserialization (JSON → Object) Serialization (Object → JSON)
───────────────────────────────── ─────────────────────────────────
API response body POST request body
SharedPreferences cache Save to file / Room
Read from assets Export / debug logging
Deserialization — JSON to object
Kotlin — Deserialize with Gsonval json = """{"id":1,"name":"Nikhil","email":"nikhil@example.com","isActive":true}"""
// Single object
val user: User = Gson().fromJson(json, User::class.java)
// List of objects
val postsJson = """[{"id":1,"title":"Hello","body":"World"}]"""
val type = object : TypeToken<List<Post>>() {}.type
val posts: List<Post> = Gson().fromJson(postsJson, type)
Serialization — object to JSON
Kotlin — Serialize with Gsonval user = User(id = 1, name = "Nikhil", email = "nikhil@example.com", isActive = true)
val jsonString = Gson().toJson(user)
// Output: {"id":1,"name":"Nikhil","email":"nikhil@example.com","isActive":true,...}
// Pretty-print for debugging
val prettyJson = GsonBuilder().setPrettyPrinting().create().toJson(user)
Save and load with SharedPreferences
Kotlin — Cache user as JSONclass UserCache(context: Context) {
private val prefs = context.getSharedPreferences("user_cache", Context.MODE_PRIVATE)
private val gson = Gson()
fun saveUser(user: User) {
prefs.edit().putString("user_json", gson.toJson(user)).apply()
}
fun loadUser(): User? {
val json = prefs.getString("user_json", null) ?: return null
return gson.fromJson(json, User::class.java)
}
fun savePostList(posts: List<Post>) {
prefs.edit().putString("posts_json", gson.toJson(posts)).apply()
}
fun loadPostList(): List<Post> {
val json = prefs.getString("posts_json", null) ?: return emptyList()
val type = object : TypeToken<List<Post>>() {}.type
return gson.fromJson(json, type)
}
}
Kotlin — Safe defaults for missing fieldsdata class Article(
val id: Int = 0,
val title: String = "",
val tags: List<String> = emptyList(),
val author: Author? = null
)
// Gson fills missing JSON fields with default values
// Use nullable types (Author?) when the field may be absent or null
6Hands-On Exercises
1
Create a JSON object for a user with nested address. Write matching Kotlin data classes.
2
Build a JSON array of 5 posts. Parse it manually using JSONArray and display titles in a list.
3
Implement a JsonParser utility with try/catch for safe JSON parsing from assets.
4
Add Gson and replace manual parsing. Use @SerializedName for a snake_case API field.
5
Deserialize a JSONPlaceholder API response into List<Post> using Gson TypeToken.
6
Serialize a user object to JSON and save it in SharedPreferences. Load it back on app restart.
7
Bonus: Use Gson with Retrofit to fetch and display posts — compare the JSON string to your Kotlin objects in Logcat.
JSON Parsing MCQ Practice
10 Basic MCQs10 Advanced MCQs
10 Basic JSON Parsing MCQs
1
JSON objects use?
ASquare brackets only
BCurly braces { key: value }
CAngle brackets
DSQL tables
Explanation: Objects hold key-value pairs.
2
JSON arrays use?
AParentheses
BCurly braces only
CSquare brackets [ item1, item2 ]
DSemicolons
Explanation: Arrays are ordered lists of values.
3
Gson converts JSON to?
ADrawables
BAPK files
CLayouts
DKotlin/Java objects (deserialization)
Explanation: Gson maps JSON fields to class properties.
4
JSONObject in Android?
Aorg.json API for manual parsing
BRoom entity
CService class
DManifest tag
Explanation: Built-in JSONObject.getString(), getInt(), etc.