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.
Json Array :
{ "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.
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.