Experience with Coroutines and Retrofit2
What is it?
Who has not read the documentation yet - I highly recommend you to familiarize yourself.
What Jetbrain writes:
Coroutines simplify asynchronous programming, leaving all the complications inside the libraries. The logic of the program can be expressed sequentially in coroutines, and the base library will implement it asynchronously for us. The library can wrap the corresponding parts of the user code in callbacks subscribing to the corresponding events, and dispatch execution to different threads (or even to different machines!). The code will remain as simple as if executed strictly sequentially.
In simple terms, this is a library for synchronous / asynchronous code execution.
What for?
Because RxJava is no longer in fashion (just kidding).
Firstly, I wanted to try something new, and secondly, I came across an article - a comparison of the speed of corutin and other methods.
Example
For example, you need to perform an operation in the background.
To get started - add to our build.gradle dependency on corutin:
We use the method in our code:
Where in context - we specify the thread pool we need - in simple cases, these are IO, Main and Default
IO - for simple operations with the API, operations with the database, shared preferencies, etc.
Main - UI thread, from where we can access View
Default - for heavy operations with high CPU load
(More in this article )
Block - the lambda we want to execute
In principle, that’s all, we get the result of the sum of squares from 1 to 1000 and at the same time we don’t block the main thread, which means no ANR
However, if our coroutine is executed for 20 seconds and during this time we have made 2 turns of the device, then we will have 3 simultaneously running blocks. Oops
And if we passed a link to activity to the block - a leak and the lack of the ability to perform operations with view in old blocks. Twice oops.
So what to do?
Doing better
Thus, we were able to stop the execution of our code in the stream, for example, when the screen is rotated.
CoroutineScope made it possible to combine the scope of all nested coroutines and, when calling job.cancel (), stopped their execution
If you plan to reuse scope after stopping execution, you need to use job.cancelChildren () instead of job.cancel () thanks Neikist for comment
At the same time, we still have the opportunity to control flows:
We connect retrofit2
Add dependencies to the hail:
We use the pen https://my-json-server.typicode.com/typicode/demo/posts as an example
We describe the retrofit interface:
Describe the returned Post model:
Our BaseRepository:
Implementation of PostsRepository:
Our BaseUseCase:
Implementation of GetPostsListUseCase:
Here is the result:
Making it Better
I am a lazy creature and every time I don’t want to drag out the entire sheet of code, so I made the necessary methods in BaseViewModel:
Now getting the Posts list looks like this:
Conclusion
I used coroutines in the prod and the code really turned out to be cleaner and more readable.
UPD:
Description of Retrofit exception handling see comment