Skip to content

Commit 617c750

Browse files
Improve README.md
1 parent d8ee85d commit 617c750

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Kotlin Coroutines and Flow - Use Cases on Android
44

5-
🎓 Learning Kotlin Coroutines and Flows for Android Development by example
5+
🎓 Learning Kotlin Coroutines and Flows for Android Development by Example
66

77
🚀 Sample implementations for real-world Android use cases
88

@@ -13,7 +13,7 @@ In the `playground` package you can play around with Coroutines and Flow example
1313

1414
## 🔧 Project Setup
1515

16-
Every use case is using its own `Activity` and `JetPack ViewModel`. The `ViewModel`s contain all the interesting Coroutine related code.
16+
Every use case is using its own `Activity` and `JetPack ViewModel`. The `ViewModel`s contain most of the interesting Coroutine-related code.
1717
`Activities` listen to `LiveData` or `StateFlow` events of the `ViewModel` and render received `UiState`s.
1818

1919
This project is using retrofit/okhttp together with a `MockNetworkInterceptor`. This lets you define how the API should behave.
@@ -89,7 +89,7 @@ This use case performs a single network request to get the latest Android Versio
8989

9090
### 2. Perform two sequential network requests
9191

92-
This use case performs two network requests sequentially. First it retrieves recent Android Versions and then it requests the features of the latest version.
92+
This use case performs two network requests sequentially. First, it retrieves recent Android Versions and then it requests the features of the latest version.
9393

9494
There are also 2 alternative implementations included. One is using old-school [callbacks](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModel.kt).
9595
The other one uses [RxJava](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/rx/SequentialNetworkRequestsRxViewModel.kt). You can compare each implementation.
@@ -101,8 +101,8 @@ If you compare all three implementations, it is really interesting to see, in my
101101

102102
Performs three network requests concurrently. It loads the feature information of the 3 most recent Android Versions. Additionally, an implementation
103103
that performs the requests sequentially is included. The UI shows how much time each implementation takes to load the data so you can see that the network
104-
requests in the concurrent version are actually performed in parallel. The included unit test is also interesting, as it shows how you can use virtual time to
105-
verify that the concurrent version really gets performed in parallel.
104+
requests in the concurrent version are indeed performed in parallel. The included unit test is also interesting, as it shows how you can use virtual time to
105+
verify that the concurrent version gets performed in parallel.
106106

107107
[[code](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModel.kt)]
108108

@@ -124,13 +124,13 @@ General networking timeouts can also be [configured in the okhttp client](https:
124124

125125
### 6. Retrying network requests
126126

127-
Demonstrates the usage of higher order functions together with coroutines. The higher order function `retry()` retries a certain suspending operation for a given amount of times.
127+
Demonstrates the usage of higher-order functions together with coroutines. The higher-order function `retry()` retries a certain suspending operation for a given amount of times.
128128
It uses an exponential backoff for retries, which means that the delay between retries increases exponentially. The behavior of the Mock API is defined in a way that it responses
129129
with 2 unsuccessful responses followed by a successful response.
130130

131131
[[code](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModel.kt)]
132132

133-
Unit tests verify the amount of request that are performed in different scenarios. Furthermore they check if the exponential backoff is working properly
133+
Unit tests verify the amount of requests that are performed in different scenarios. Furthermore, they check if the exponential backoff is working properly
134134
by asserting the amount of elapsed virtual time.
135135

136136
### 7. Network requests with timeout and retry
@@ -174,7 +174,7 @@ In the respective unit test, we have to pass the testDispatcher to the ViewModel
174174

175175
UseCase#10 has a problem. It is not able to prematurely cancel the calculation because it is not cooperative regarding cancellation. This leads to wasted device resources and
176176
memory leaks, as the calculation is not stopped and the ViewModel is retained longer than necessary. This use case now fixes this issue. The UI now also has a "Cancel Calculation"
177-
Button. Note: Only the calculation can be cancelled prematurely but not the `toString()` conversion.
177+
Button. Note: Only the calculation can be canceled prematurely but not the `toString()` conversion.
178178

179179
There are several ways to make your coroutines cooperative regarding cancellation: You can use either use `isActive()`, `ensureActive()` or `yield()`.
180180
More information about cancellation can be found [here](https://medium.com/androiddevelopers/exceptions-in-coroutines-ce8da1ec060c)
@@ -183,26 +183,26 @@ More information about cancellation can be found [here](https://medium.com/andro
183183

184184
### 12. Offload expensive calculation to several Coroutines
185185

186-
The factorial calculation here is not performed by a single coroutine, but by an amount of coroutines that can be defined in the UI. Each coroutine calculates the factorial of a sub-range.
186+
The factorial calculation here is not performed by a single coroutine, but by a number of coroutines that can be defined in the UI. Each coroutine calculates the factorial of a sub-range.
187187

188188
[[code viewmodel](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/CalculationInSeveralCoroutinesViewModel.kt)]
189189
[[code factorial calculator](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculator.kt)]
190190

191191
### 13. Exception Handling
192192

193-
This use case demonstrates different ways of handling exceptions using `try/catch` and `CoroutineExceptionHandler`. It also demonstrates when you should to use `supervisorScope{}`: In situations when you don't want a failing coroutine to cancel
194-
its sibling coroutines. In one implementation of this use case, the results of the successful responses are shown even tough one response wasn't successful.
193+
This use case demonstrates different ways of handling exceptions using `try/catch` and `CoroutineExceptionHandler`. It also demonstrates when you should use `supervisorScope{}`: In situations when you don't want a failing coroutine to cancel
194+
its sibling coroutines. In one implementation of this use case, the results of the successful responses are shown even though one response wasn't successful.
195195

196196
[[code](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase13/ExceptionHandlingViewModel.kt)]
197197

198198
### 14. Continue Coroutine execution when the user leaves the screen
199199

200-
Usually, when the user leaves the screen, the `ViewModel` gets cleared and all the coroutines launched in `viewModelScope` get cancelled. Sometimes, however, we want a certain coroutine operation to be continued
200+
Usually, when the user leaves the screen, the `ViewModel` gets cleared and all the coroutines launched in `viewModelScope` get canceled. Sometimes, however, we want a certain coroutine operation to be continued
201201
when the user leaves the screen. In this use case, the network request keeps running and the results still get inserted into the database
202-
cache when the user leaves the screen. This makes sense in real world application as we don't want to cancel an already started background "cache sync".
202+
cache when the user leaves the screen. This makes sense in real-world applications as we don't want to cancel an already started background "cache sync".
203203

204204

205-
You can test this behavior in the UI by clearing the database, then loading the Android version and instantly close the screen. You will see in LogCat that the response
205+
You can test this behavior in the UI by clearing the database, then loading the Android version and instantly closing the screen. You will see in LogCat that the response
206206
still gets executed and the result still gets stored. The respective unit test `AndroidVersionRepositoryTest` also verifies this behavior. Check out this [blogpost](https://medium.com/androiddevelopers/coroutines-patterns-for-work-that-shouldnt-be-cancelled-e26c40f142ad) for details of the implementation.
207207

208208
[[code viewmodel](app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/ContinueCoroutineWhenUserLeavesScreenViewModel.kt)]
@@ -238,7 +238,7 @@ You can play around and check the performance of different configurations!
238238

239239
This simple use case shows how to consume values from a `DataSource` that emits live stock information and how to display them in the UI.
240240

241-
The datasource exposes a flow which is built with the `flow{}` flow builder. It fetches fresh stock information every 5 seconds from a mocked endpoint.
241+
The datasource exposes a `Flow` which is built with the `flow{}` flow builder. It fetches fresh stock information every 5 seconds from a mocked endpoint.
242242

243243
A `LiveData` property that exposes the `UiState` in the `ViewModel` is created by using the `.asLiveData()` terminal operator.
244244
This use case also shows how to use the `map` intermediate operator and the `onStart` lifecycle operator.
@@ -252,7 +252,7 @@ It uses some basic intermediate operators, like `withIndex`, `map`, `take` and `
252252

253253
The third use case shows how to properly implement exception handling with flows.
254254

255-
It uses the `catch` operator to handle exceptions of our flow in the `ViewModel`, and uses the `retry ` operator to retry failed network requests in the `DataSource`.
255+
It uses the `catch` operator to handle exceptions of our flow in the `ViewModel` and uses the `retry ` operator to retry failed network requests in the `DataSource`.
256256

257257
### 4. Exposing Flows in the ViewModel
258258

0 commit comments

Comments
 (0)