android kotlin - Volley JsonObjectRequest

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:

  1. MainActivity.kt: This file is the core activity class that handles user interaction and network requests.
  2. VolleySingleton.kt: This file implements a singleton class to manage the Volley request queue, ensuring only one instance exists throughout the application.
  3. 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:

  1. Initializes UI elements (button, progress bar, text view) by referencing their IDs from the layout file.
  2. Defines a URL containing a JSON object with an array of student information.
  3. Implements a click listener for the button:
    • Disables the button to prevent multiple requests.
    • Shows the progress bar to indicate network activity.
    • Creates a JsonObjectRequest using 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 VolleySingleton class.

The response listener parses the JSON object:

  1. Extracts the student array from the response object.
  2. Clears the text view content.
  3. Loops through each student object in the array.
  4. Extracts individual student data (firstName, lastName, age) for each object.
  5. 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:

  1. Implements the Singleton pattern to create a single instance of the class throughout the application.
  2. Provides a method getInstance to access the singleton instance.
  3. Initializes a RequestQueue object using Volley. applicationContext is used to prevent leaks.
  4. Defines a method addToRequestQueue to 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.


MainActivity.kt

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)
        }
    }
}
VolleySingleton.kt

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)
    }
}
activity_main.xml

<?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>
gradle dependencies

// Volley network library
implementation 'com.android.volley:volley:1.2.1'
More android kotlin tutorials