Introduction
This code demonstrates how to fetch a JSON object from a URL using Volley, a popular networking library for Android development written in Kotlin. The code is divided into three parts:
- MainActivity.kt: This file is the core activity class that handles user interaction and network requests.
 - VolleySingleton.kt: This file implements a singleton class to manage the Volley request queue, ensuring only one instance exists throughout the application.
 - activity_main.xml: This file defines the user interface layout of the main activity with a button, a progress bar, and a text view.
 
Breakdown of MainActivity.kt
The MainActivity class:
- Initializes UI elements (button, progress bar, text view) by referencing their IDs from the layout file.
 - Defines a URL containing a JSON object with an array of student information.
 - Implements a click listener for the button:
- Disables the button to prevent multiple requests.
 - Shows the progress bar to indicate network activity.
 - Creates a 
JsonObjectRequestusing Volley:- Specifies the HTTP method (GET) and the target URL.
 - Sets the response listener to handle successful JSON object retrieval.
 - Sets the error listener to handle network or parsing errors.
 
 - Adds the request to the Volley request queue managed by the 
VolleySingletonclass. 
 
The response listener parses the JSON object:
- Extracts the student array from the response object.
 - Clears the text view content.
 - Loops through each student object in the array.
 - Extracts individual student data (firstName, lastName, age) for each object.
 - Appends the formatted student information to the text view.
 
The error listener displays any error message received during the request.
Breakdown of VolleySingleton.kt
The VolleySingleton class:
- Implements the Singleton pattern to create a single instance of the class throughout the application.
 - Provides a method 
getInstanceto access the singleton instance. - Initializes a 
RequestQueueobject using Volley.applicationContextis used to prevent leaks. - Defines a method 
addToRequestQueueto add network requests to the queue. 
Summary
This code showcases how to leverage Volley for fetching JSON data from a remote server in an Android application with Kotlin. It demonstrates making a GET request, parsing the JSON response, extracting relevant data, and displaying it in a user-friendly format. The use of a singleton for the request queue ensures efficient management of network requests.
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.JsonObjectRequest
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 object
        val url = "https://pastebin.com/raw/2bW31yqa"
        // get json object from url using volley network library
        button.setOnClickListener {
            // disable the button itself
            it.isEnabled = false
            progressBar.visibility = View.VISIBLE
            // request json object response from the provided url
            val request = JsonObjectRequest(
                Request.Method.GET, // method
                url, // url
                null, // json request
                { response -> // response listener
                    try {
                        val obj: JSONObject = response
                        val array = obj.getJSONArray("students")
                        textView.text = ""
                        // loop through the array elements
                        for (i in 0 until  array.length()){
                            // get current json object as student instance
                            val student: JSONObject = array.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 JsonArrayRequest
 - android kotlin - Volley image request
 - android kotlin - Volley string request
 - android kotlin - Chip center text
 - android kotlin - EditText phone number validation
 - android kotlin - EditText space validation
 - android kotlin - EditText email validation
 - android kotlin - EditText select all on focus
 - android kotlin - EditText live characters count
 - android kotlin - EditText first letter capitalization
 - android kotlin - Show soft keyboard when EditText is focused
 - android kotlin - EditText hide error
 - android kotlin - EditText allow only certain characters
 - android kotlin - Set EditText digits programmatically
 - android kotlin - EditText allow only positive numbers