loading...

Kotlin RxJava Retrofit tutorial

paulodhiambo profile image paul odhiambo Updated on ・3 min read

Kotlin Retrofit Rxjava

This is a continuation of the previous tutorial where we made network calls
using retrofit and kotlin. Go through the first tutorial to continue.

What is RxJava

Reactivex is a library for composing asynchronous and event based programs
by using observable sequences. It frees you from tangled webs of callbacks,
and thereby makes your code more readable and less prone to bugs.
With Retrofit we can incorporate RxJava to make our code better and our application more efficient. Retrofit also comes with an adapter for including RxJava in our network calls.

Dependencies

//RxJava adapter
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.0'
    //RxJava
    implementation 'io.reactivex.rxjava2:rxjava:2.2.12'
    //RxAndroid
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'


`
The Interface

Nothing much changes in the interface containing our endpoints. It's only
that we change the return of our functions from call to observable.

What are these Observables

An observable is a class that gives us data or events. It is used to perform
actions and give out the results.

Snippets

`

package com.odhiambopaul.movies.network

import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Query

interface TmdbEndpoints {

    @GET("/3/movie/popular")
    fun getMovies(@Query("api_key") key: String): Observable<PopularMovies>

}


`
The Service Class

Next we add the RxJava adapter to our retrofit object to include RxJava to our network
network calls and allow us to create the observable when making the call.

Snippets

`

package com.odhiambopaul.movies.network

import com.odhiambopaul.movies.util.BASE_URL
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

object ServiceBuilder {
    private val client = OkHttpClient
        .Builder()
        .build()

    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build()
        .create(TmdbEndpoints::class.java)

    fun buildService(): TmdbEndpoints {
        return retrofit
    }
}


`
MainActivity.kt

Now it is time to make the network call. First we create a CompositeDisposable.

A CompositeDisposable is a class that helps us to manage all our disposables.
Disposable are the connections between Observable and observer. When we
create observables, and they emit data, a stream is created which later needs to be removed it takes up resources. This stream is the called a disposable. Since
you can create more than one disposable , it would be tiresome to clear them one by one, hence we use a CompositeDisposable which will contain all the disposables created and they can be cleared by just clearing the CompositeDisposable. We use the add() method to add one disposable in our activity. We use the subscribeOn() and/or with the observeOn() method to specify the threads on which the call should be executed on. If we specify the subscribeOn() only, we tell the app to run the call on the current thread. Then we call the subscribe() method to getthe data or error.

Response/Error

Inside the subscribe() method we have two lambda expressions. The first oneis always executed if our call was successful and it returns our value i.e PopularMovies object,then we call the onResponse function that we create to handle our response. If there is an error in our application then the second expression is executed to return a throwable then we call a function in our case, onFailure

Snippets

`

package com.odhiambopaul.movies.ui.home

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.odhiambopaul.movies.network.PopularMovies
import com.odhiambopaul.movies.R
import com.odhiambopaul.movies.network.ServiceBuilder
import com.odhiambopaul.movies.util.api_key
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        val compositeDisposable = CompositeDisposable()
        compositeDisposable.add(
            ServiceBuilder.buildService().getMovies(api_key)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({response -> onResponse(response)}, {t -> onFailure(t) }))

    }

    private fun onFailure(t: Throwable) {
        Toast.makeText(this,t.message, Toast.LENGTH_SHORT).show()
    }

    private fun onResponse(response: PopularMovies) {
        progress_bar.visibility = View.GONE
        recyclerView.apply {
            setHasFixedSize(true)
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter =
                MoviesAdapter(response.results)
        }
    }
}


`
With RxJava we have managed to reduce the number of lines of code and the resultant code is clean and readable.

The full project can be found in my repo at Movies

Posted on by:

paulodhiambo profile

paul odhiambo

@paulodhiambo

I'm a passionate Android and backend developer.

Discussion

markdown guide