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!