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🤗

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay