DEV Community

Cover image for Call API's With Kotlin-Coroutines In Your Android Application
Saketh
Saketh

Posted on

6 1

Call API's With Kotlin-Coroutines In Your Android Application

Before Getting Started I Suggest You Understand What's Actually A Coroutine Jobs Are, Which I Have Discussed In The Previous Blog In This Series. And Make Sure That You Have Included Coroutines Dependency If It's Not Included:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
Enter fullscreen mode Exit fullscreen mode

-> Until The Previous Blogs In This Series I Have Shown The Usage And Purpose Of The Kotlin-Coroutines When You Are Getting Started With It, It's Time For Building Something With It😈.

Pre-requisites Before Moving To Further:

-> Make Sure That You Have Added Volley Library Dependency From Which We'll Be Networking[You Can Use Retrofit Too]

dependencies {
    ...
    implementation("com.android.volley:volley:1.2.0")
}
Enter fullscreen mode Exit fullscreen mode

-> Make Sure You Have Added Coil Library Dependency From Which We'll Be Loading Cat Images😺:

dependencies {
    ...
    implementation("io.coil-kt:coil:1.3.0")
}
Enter fullscreen mode Exit fullscreen mode

-> And Of Course Kotlin-Coroutines Dependency Too:

dependencies {
    ...
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
}
Enter fullscreen mode Exit fullscreen mode

-> And Make Sure You Have Added Internet Permission In Your Manifest File So That We Can Make A Network Request Successfully:

<uses-permission android:name="android.permission.INTERNET"/>
Enter fullscreen mode Exit fullscreen mode

Designing The Layout

  • We'll Be Adding An ImageView And A Button In Our XML File || Layout File.

  • In Our ImageView, We'll Be Showing The Cat Images Though Coil After Making the API Request Through Volley.

  • And When Button Will Be Clicked We'll Call Our API Again So That Another Random Image Of Cats😺 Can Be Show In Our ImageView Respectively.

Adding An ImageView:

  • Depending On Your Root Layout You Can Change Those Attributes:
<ImageView
            android:id="@+id/apiImageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="25dp"
            android:layout_marginEnd="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
Enter fullscreen mode Exit fullscreen mode

Adding A Button:

  • Depending On Your Root Layout You Can Change Those Attributes:
<com.google.android.material.button.MaterialButton
            android:id="@+id/apiBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:fontFamily="casual"
            android:text="Call API Again"
            android:textAllCaps="false"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="@+id/apiImageView"
            app:layout_constraintStart_toStartOf="@+id/apiImageView"
            app:layout_constraintTop_toBottomOf="@+id/apiImageView" />
Enter fullscreen mode Exit fullscreen mode
Your Final Layout Code May Look Like This:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true"
    tools:context=".FirstFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="ScrollViewSize">

        <ImageView
            android:id="@+id/apiImageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="25dp"
            android:layout_marginEnd="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.google.android.material.button.MaterialButton
            android:id="@+id/apiBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:fontFamily="casual"
            android:text="Call API Again"
            android:textAllCaps="false"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="@+id/apiImageView"
            app:layout_constraintStart_toStartOf="@+id/apiImageView"
            app:layout_constraintTop_toBottomOf="@+id/apiImageView" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Enter fullscreen mode Exit fullscreen mode

xml final.png

  • Well, That's All For Layout. I Highly Recommend To Play Around With The Layout FIle According To Your Imagination.

Crafting Our Application[Logic]:

  • First Things First, Let's Assign A Variable Which We'll Use Further For Requesting:
private lateinit var requestQueue: RequestQueue
Enter fullscreen mode Exit fullscreen mode

Now, We'll be Creating A Function Named apiCall() In Which We'll Be Passing imageView As A Parameter:

private fun apiCall(imageView: ImageView) {

}
Enter fullscreen mode Exit fullscreen mode
  • Let's Launch A Coroutine By Implementing lifecycleScope Scope Through IO Dispatcher As We Are Working With Networking Stuff:
 private fun apiCall(imageView: ImageView) {
        lifecycleScope.launch(Dispatchers.IO) {

        }
}
Enter fullscreen mode Exit fullscreen mode
  • Moment We Are Waiting For, Simply Request API As You Do In Regular. I'm Gonna Use Volley As I Mentioned Earlier, BTW I'm Using This API Which Is In JSON Format-> https://thatcopy.pw/catapi/rest/:

-> As You Can See That Cat Image's URL Is Set To url Key:

api.png

  • This Is How Your API Request May Look Like:
private fun apiCall(imageView: ImageView) {
        lifecycleScope.launch(Dispatchers.IO) {
            val apiUrl = "https://thatcopy.pw/catapi/rest/"
            val jsonObjectRequest = JsonObjectRequest(Request.Method.GET, apiUrl, null, {
                val imageURL=it.getString("url") // -> Will Get Our Cat Image URL
                imageView.load(imageURL)
            }, {
                Log.d("API Request Error", "${it.printStackTrace()}")
            })
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • After Implementing All Those Request Stuff Let's Add Our jsonObjectRequest Variable To requestQueue Variable So That We Can Move Further And Your apiCall() Function SHould Look Like This Now:
private fun apiCall(imageView: ImageView) {
        lifecycleScope.launch(Dispatchers.IO) {
            val apiUrl = "https://thatcopy.pw/catapi/rest/"
            val jsonObjectRequest = JsonObjectRequest(Request.Method.GET, apiUrl, null, {
                val imageURL=it.getString("url") // -> Will Get Our Cat Image URL
                imageView.load(imageURL)
            }, {
                Log.d("API Request Error", "${it.printStackTrace()}")
            })
            requestQueue.add(jsonObjectRequest) // -> Added jsonObjectRequest To requestQueue
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • Now, For Loading Image, I Have Created Another Function Named loadImage() In Which I Have Launched A Coroutine With apiCall() Function For Networking With API Through Main Dispatcher So That We Can Work With Main Thread:
private fun loadImage(imageView: ImageView){
        lifecycleScope.launch(Dispatchers.Main){
            apiCall(imageView)
        }
    }
Enter fullscreen mode Exit fullscreen mode

Main Stuffâš¡

  • Let's Call loadImage() Function In Main Thread In Which We Have Already Made API Request Through apiCall() Function:
loadImage(view.apiImageView)
Enter fullscreen mode Exit fullscreen mode
  • Also, We Have To Call loadImage() Function When Button Is Clicked So That We Can Call API Again And Show Cat Images😺:
view.apiBtn.setOnClickListener {
            loadImage(view.apiImageView)
        }
Enter fullscreen mode Exit fullscreen mode

At Last

  • We'll Add Volley In Our requestQueue Variable Which We Have Created Earlier And Added jsonObjectRequest:
requestQueue = Volley.newRequestQueue(this.context)
Enter fullscreen mode Exit fullscreen mode
Your Final Kotlin File May Look Like This:
package com.example.name

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.lifecycle.lifecycleScope
import coil.load
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import kotlinx.android.synthetic.main.fragment_first.view.*
import kotlinx.coroutines.*

class FirstFragment : Fragment() {
    private lateinit var requestQueue: RequestQueue
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_first, container, false)
        requestQueue = Volley.newRequestQueue(this.context)
        loadImage(view.apiImageView)
        view.apiBtn.setOnClickListener {
            loadImage(view.apiImageView)
        }
        return view
    }

    private fun apiCall(imageView: ImageView) {
        lifecycleScope.launch(Dispatchers.IO) {
            val apiUrl = "https://thatcopy.pw/catapi/rest/"
            val jsonObjectRequest = JsonObjectRequest(Request.Method.GET, apiUrl, null, {
                val imageURL=it.getString("url") // -> Will Get Our Cat Image URL
                imageView.load(imageURL)
            }, {
                Log.d("API Request Error", "${it.printStackTrace()}")
            })
            requestQueue.add(jsonObjectRequest) // -> Added jsonObjectRequest To requestQueue
        }
    }
    private fun loadImage(imageView: ImageView){
        lifecycleScope.launch(Dispatchers.Main){
            apiCall(imageView)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Launch The Application After Successful Build:

api in coroutines.gif

  • As You Can See That It's Working Like Charmâš¡.

Playaround With Coroutines And Other API's😉

Well That's All For Now🙌

Bye🤗

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Sentry growth stunted Image

If you are wasting time trying to track down the cause of a crash, it’s time for a better solution. Get your crash rates to zero (or close to zero as possible) with less time and effort.

Try Sentry for more visibility into crashes, better workflow tools, and customizable alerts and reporting.

Switch Tools