An Efficient way to manage API calls with RxRetrofit

Prologue

Android is becoming popular day by day and thousands of apps are being published on Play Store. To survive in this competition, the User experience matters a lot. The app crash is the worst User experience, in other words we can say 1 billion dollar mistake. So I am going to explain how to use RxRetrofit efficiently to make API calls.

Problem

The most common mistake made by the Android developer is while making an API call and not handling the fact that the user can exit the app or press the back button, before the API call returns. The result is app crash!

In more detail, when an API is hit, that network call is being performed on the background thread and based on response the UI needs to be updated in UI thread. Now, when the background thread is running and the back button is pressed, the current screen (Activity or Fragment) will be popped out from the stack. After this when data is received from the API and an attempt to update the UI will result in a crash as the current screen (Activity or Fragment) will not be in the stack.

Solution

Make API calls using RxRetrofit !!

Example

RetrofitApiClient.createService(ApiInterface::class.java)
   .callLoginApi(“email”,”password”)
   .observeOn(AndroidSchedulers.mainThread()) // On UI thread
   .subscribeOn(Schedulers.io()) // On background thread 
   .subscribe({ response -> // On Success 

         // App will crash on the below line
         editTextOtp.setText(response?.body()?.otp)
         buttonLogin.setText("Verify OTP")

   }, {
       // On Error (Could not reach to the server)
   })

According to the above example, when you hit the Login API and immediately press the back button (Activity or Fragment removed from the stack) then you get the response from the API in the subscribe() method, you try to update the UI and the app will crash!

Use the Disposable interface of the RxJava which is used with RxRetrofit.

See the below example :

public interface Disposable {
   void dispose();  // Dispose the resource or an operation.
   boolean isDisposed(); // Returns true if this resource has been disposed.
}


Let’s implement it in the above example,

1) private var disposableLoginAPI: Disposable? = null // Globally
2) 
disposableLoginAPI = 
RetrofitApiClient.createService(ApiInterface::class.java)
   .callLoginApi(“email”,”password”)
   .observeOn(AndroidSchedulers.mainThread()) // On UI thread
   .subscribeOn(Schedulers.io()) // On background thread 
   .subscribe({ response -> // On Success 

         editTextOtp.setText(response?.body()?.otp)
         buttonLogin.setText("Verify OTP")

   }, {
       // On Error (Could not reach to the server)
   })

The subscribe() returns disposable so initialize the disposable with it.

3) override fun onStop() {
   super.onStop()

     // If it's not disposed then dispose  
    if (disposableLoginAPI?.isDisposed == false) {
         disposableLoginAPI?.dispose() // Magic!
    }  
} 

So once you are about to leave the screen (Activity or Fragment), in the onStop() method, dispose() method will dispose the API call and there will be no response in the subscribe() method, so UI will not be updated and the app will not crash.

For Multiple API calls

You can use CompositeDisposable to add multiple disposable objects:

val listOfDisposables=CompositeDisposable() // Init object

//Adding multiple disposables
listOfDisposables.add(disposableLogin!!)
listOfDisposables.add(disposableForgotPassword!!)

And finally dispose in the onStop() method.

override fun onStop() {
   super.onStop()

   listOfDisposables.dispose()  // Dispose all the disposables 
} 

Happy Coding!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.