Kotlin coroutines with retrofit || Kotlin Tutorial

 

Kotlin Coroutine :

Kotlin coroutine provide a safer way of asynchronous coding. A coroutine is light weight thread which run parallel and can also communicate with each other depending upon the requirement.

Creating and using a coroutine is a simple as well maintaining them too.Performance is also quite good when compared to traditional threads.

To start a Kotlin coroutine we just need to provide a launch and in between the braces need to provide the block of code to be executed.

launch{ ..... }

 

Also with the Kotlin coroutine we can also run the task which has a return value based on which the next process run’s.

For example we need to fetch the result of a method whether it’s true or not and proceed further accordingly.So for this purpose we can start a Kotlin coroutine as

async{......}

there will be await() function which will return the result.

 

With the help of suspend functions let’s see a simple tutorial on how to execute android Kotlin coroutines.

 

Kotlin coroutine video tutorial :

Go through the below video tutorial for more implementation details.

 

Add project retrofit and coroutines dependency’s

// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
// coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"

 

Add internet permission’s in manifest file.

<uses-permission android:name="android.permission.INTERNET"/>

 

 

Project Structure :

This image depicts the usage of kotlin coroutine project structure implementation.

Kotlin coroutine

 

Json Array :

Here we are considering three fields phone, name, email for generating the json list.
{
  "phone": "+91-9876543210", 
  "name": "abhi", 
  "email": "abhi@gmail.com"
}

 

User.class

Fetch the json and store into the model class. Want to generate a model class automatically?

import com.google.gson.annotations.SerializedName;

public class User {
    @SerializedName("name")
    private String Name;
    @SerializedName("email")
    private String Email;
    @SerializedName("phone")
    private String Phone;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getEmail() {
        return Email;
    }

    public void setEmail(String email) {
        Email = email;
    }

    public String getPhone() {
        return Phone;
    }

    public void setPhone(String phone) {
        Phone = phone;
    }
}

 

Network :

RetrofitFactory.class

Create a retrofit builder, add base url, client.

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitFactory {
    var client = OkHttpClient()
    fun makeRetrofitService(): RestApiService {
        return Retrofit.Builder()
            .baseUrl("https://www.json-generator.com/api/json/get/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build().create(RestApiService::class.java)
    }
}

 

RestApiService.class

Create a getUser method and declare the suspend function and fetch the response and store in the model class generated above.

import com.abhishek.kotlincoroutines.Model.User
import retrofit2.Response
import retrofit2.http.GET


interface RestApiService {
    @GET("coQhYUwpNK?indent=2")
    suspend fun getUsers(): Response<User>
}

 

activity_main.xml

Now we will add three textview’s to populate the values and display them accordingly

<?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="#C5ABF3"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/txtName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        android:textSize="25dp"
        android:textColor="#ffffff"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.488"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.395" />

    <TextView
        android:id="@+id/txtEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="28dp"
        android:text="email"
        android:textSize="25dp"
        android:textColor="#ffffff"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtName" />

    <TextView
        android:id="@+id/txtPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="phone"
        android:textSize="25dp"
        android:textColor="#ffffff"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.566" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.class

Initialize RetrofitFactory and RestApiService. Inside coroutine scope fetch the data from remote api, and if there is error display a toast so that user knows the result.

CoroutineScope(Dispatchers.IO).launch {
    val response = service.getUsers()
    try {
        withContext(Dispatchers.Main) {
            if (response.isSuccessful) {
                response.body()?.let {
                    users = it
                    setData(users)
                }
            } else {
                Toast.makeText(this@MainActivity, "Error occured", Toast.LENGTH_SHORT)
                    .show()
            }
        }
    } catch (e: HttpException) {
        Log.e("REQUEST", "Exception ${e.message}")
    } catch (e: Throwable) {
        Log.e("REQUEST", "Ooops: Something else went wrong")
    }

 

On Success set data to model class.

// setting data from response to model
users = it

// passing data to set data method
setData(users)

 

Set data using synthetic binding

fun setData(user: User) {

    txtName.setText(user.name)
    txtEmail.setText(user.email)
    txtPhone.setText(user.phone)
}
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.abhishek.kotlincoroutines.Model.User
import com.abhishek.kotlincoroutines.Network.RetrofitFactory
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
import retrofit2.HttpException

class MainActivity : AppCompatActivity() {

    var users = User()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val service = RetrofitFactory.makeRetrofitService()
        CoroutineScope(Dispatchers.IO).launch {
            val response = service.getUsers()
            try {
                withContext(Dispatchers.Main) {
                    if (response.isSuccessful) {
                        response.body()?.let {
                            users = it
                            setData(users)
                        }
                    } else {
                        Toast.makeText(this@MainActivity, "Error occured", Toast.LENGTH_SHORT)
                            .show()
                    }
                }
            } catch (e: HttpException) {
                Log.e("REQUEST", "Exception ${e.message}")
            } catch (e: Throwable) {
                Log.e("REQUEST", "Ooops: Something else went wrong")
            }
        }

    }

    fun setData(user: User) {

        txtName.setText(user.name)
        txtEmail.setText(user.email)
        txtPhone.setText(user.phone)
    }

}

Kotlin coroutine output :

Find the final output of the code below data is fetched from source and set to views accordingly using kotlin coroutine.

 

Kotlin coroutine

 

If you have any query on Kotlin Coroutine tutorial do let us know in the comment section below.If you like this tutorial do like and share for more interesting tutorials.

Show Buttons
Hide Buttons
Read previous post:
LiveData || MVVM || Retrofit || Part 2

  For the initial part of tutorial on android livedata please refer the link provided https://androidcoding.in/2020/05/05/livedata_tutorial/ We have discussed live...

Close