Android Kotlin - Volley JsonArrayRequest: Summary
This code demonstrates fetching a JSON array from a URL and displaying its content in a scrollable TextView using Volley, a popular Android networking library. The user clicks a button to trigger the request, and the response is parsed to extract student data (first name, last name, and age). This data is then displayed in a formatted way within the TextView.
Android Kotlin - Volley JsonArrayRequest: Breakdown
The code is divided into three parts:
MainActivity.kt: This is the main activity class that handles user interaction and network requests. It defines the layout elements (button, progress bar, and text view) and their functionalities. When the button is clicked, it:
- Disables the button to prevent multiple clicks.
 - Shows the progress bar to indicate ongoing network activity.
 - Creates a 
JsonArrayRequestobject specifying the URL, method (GET), success and error listeners. - Adds the request to Volley's request queue using a singleton instance of 
VolleySingleton. 
VolleySingleton.kt: This class implements a singleton pattern to manage Volley's request queue. It provides a static method
getInstanceto access the single instance and a methodaddToRequestQueueto add network requests to the queue. This approach ensures a single instance of the queue exists throughout the application.activity_main.xml: This file defines the layout of the activity in XML format. It includes a button to trigger the network request, a progress bar to indicate loading, and a text view to display the parsed data.
The code utilizes org.json libraries for parsing the JSON response. It iterates through the JSON array elements, extracts individual student data (names and age), and appends the formatted information to the text view.
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.View
import android.widget.*
import com.android.volley.Request
import com.android.volley.toolbox.JsonArrayRequest
import org.json.JSONException
import org.json.JSONObject
class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)
        val progressBar = findViewById<ProgressBar>(R.id.progressBar)
        val textView = findViewById<TextView>(R.id.textView)
        // make text view content scrollable
        textView.movementMethod = ScrollingMovementMethod()
        // url to get json array
        val url = "https://pastebin.com/raw/Em972E5s"
        // get json array from url using volley network library
        button.setOnClickListener {
            // disable the button itself
            it.isEnabled = false
            progressBar.visibility = View.VISIBLE
            // request json array response from the provided url
            val request = JsonArrayRequest(
                Request.Method.GET, // method
                url, // url
                null, // json request
                {response -> // response listener
                    try {
                        textView.text = ""
                        // loop through the array elements
                        for (i in 0 until  response.length()){
                            // get current json object as student instance
                            val student: JSONObject = response.getJSONObject(i)
                            // get the current student (json object) data
                            val firstName: String = student
                                .getString("firstname")
                            val lastName: String = student
                                .getString("lastname")
                            val age: Int = student.getInt("age")
                            // display the formatted json data in text view
                            textView.append("$firstName " +
                                    "$lastName\nAge : $age\n\n")
                        }
                    }catch (e: JSONException){
                        textView.text = e.message
                    }
                    progressBar.visibility = View.INVISIBLE
                },
                {error -> // error listener
                    textView.text = error.message
                    progressBar.visibility = View.INVISIBLE
                }
            )
            // add network request to volley queue
            VolleySingleton.getInstance(applicationContext)
                .addToRequestQueue(request)
        }
    }
}
package com.cfsuman.kotlintutorials
import android.content.Context
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.Volley
class VolleySingleton constructor(context: Context) {
    companion object {
        @Volatile
        private var INSTANCE: VolleySingleton? = null
        fun getInstance(context: Context) =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: VolleySingleton(context).also {
                    INSTANCE = it
                }
            }
    }
    private val requestQueue: RequestQueue by lazy {
        // applicationContext is key, it keeps you from leaking the
        // Activity or BroadcastReceiver if someone passes one in.
        Volley.newRequestQueue(context.applicationContext)
    }
    fun <T> addToRequestQueue(req: Request<T>) {
        requestQueue.add(req)
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:padding="24dp">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Run Volley"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="@+id/button"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintTop_toTopOf="@+id/button" />
    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        android:fontFamily="sans-serif"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button"
        tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
// Volley network library
implementation 'com.android.volley:volley:1.2.1'
- android kotlin - Volley JsonObjectRequest
 - android kotlin - Volley image request
 - android kotlin - Volley string request
 - android kotlin - Chip center text
 - android kotlin - Chip border color
 - android kotlin - Chip background color
 - android kotlin - Chip checked color programmatically
 - android kotlin - ChipGroup get selected chips
 - android kotlin - ChipGroup add chip programmatically
 - android kotlin - ChipGroup single selection
 - android kotlin - NumberPicker string values
 - android kotlin - NumberPicker divider height
 - android kotlin - NumberPicker remove divider
 - android kotlin - NumberPicker divider color
 - android kotlin - NumberPicker text size