Skip to content

Commit ae55ca7

Browse files
Clear implementations for branch "coroutines_course_empty"
1 parent d6820f5 commit ae55ca7

16 files changed

+10
-603
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,13 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
54
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
6-
import kotlinx.coroutines.launch
7-
import timber.log.Timber
85

96
class PerformSingleNetworkRequestViewModel(
107
private val mockApi: MockApi = mockApi()
118
) : BaseViewModel<UiState>() {
129

1310
fun performSingleNetworkRequest() {
14-
uiState.value = UiState.Loading
15-
viewModelScope.launch {
16-
try {
17-
val recentAndroidVersions = mockApi.getRecentAndroidVersions()
18-
uiState.value = UiState.Success(recentAndroidVersions)
19-
} catch (exception: Exception) {
20-
Timber.e(exception)
21-
uiState.value = UiState.Error("Network Request failed!")
22-
}
23-
}
11+
2412
}
2513
}
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,14 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase10
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
54
import kotlinx.coroutines.CoroutineDispatcher
65
import kotlinx.coroutines.Dispatchers
7-
import kotlinx.coroutines.launch
8-
import kotlinx.coroutines.withContext
9-
import java.math.BigInteger
10-
import kotlin.system.measureTimeMillis
116

127
class CalculationInBackgroundViewModel(
138
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
149
) : BaseViewModel<UiState>() {
1510

1611
fun performCalculation(factorialOf: Int) {
17-
uiState.value = UiState.Loading
18-
viewModelScope.launch {
19-
try {
20-
var result: BigInteger = BigInteger.ZERO
21-
val computationDuration = measureTimeMillis {
22-
result = calculateFactorialOf(factorialOf)
23-
}
2412

25-
var resultString = ""
26-
val stringConversionDuration = measureTimeMillis {
27-
resultString = convertToString(result)
28-
}
29-
30-
uiState.value =
31-
UiState.Success(resultString, computationDuration, stringConversionDuration)
32-
} catch (exception: Exception) {
33-
UiState.Error("Error while calculating result")
34-
}
35-
}
3613
}
37-
38-
// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
39-
private suspend fun calculateFactorialOf(number: Int): BigInteger =
40-
withContext(defaultDispatcher) {
41-
var factorial = BigInteger.ONE
42-
for (i in 1..number) {
43-
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
44-
}
45-
factorial
46-
}
47-
48-
private suspend fun convertToString(number: BigInteger): String =
49-
withContext(defaultDispatcher) {
50-
number.toString()
51-
}
5214
}

app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase11/CooperativeCancellationViewModel.kt

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,22 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
33
import androidx.lifecycle.LiveData
44
import androidx.lifecycle.MutableLiveData
55
import androidx.lifecycle.ViewModel
6-
import androidx.lifecycle.viewModelScope
7-
import kotlinx.coroutines.*
8-
import java.math.BigInteger
9-
import kotlin.system.measureTimeMillis
6+
import kotlinx.coroutines.CoroutineDispatcher
7+
import kotlinx.coroutines.Dispatchers
108

119
class CooperativeCancellationViewModel(
1210
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
1311
) : ViewModel() {
1412

15-
private var calculationJob: Job? = null
16-
1713
fun performCalculation(factorialOf: Int) {
18-
uiState.value = UiState.Loading
19-
calculationJob = viewModelScope.launch {
20-
try {
21-
22-
var result: BigInteger = BigInteger.ZERO
23-
val computationDuration = measureTimeMillis {
24-
result = calculateFactorialOf(factorialOf)
25-
}
26-
27-
var resultString = ""
28-
val stringConversionDuration = measureTimeMillis {
29-
resultString = convertToString(result)
30-
}
3114

32-
uiState.value =
33-
UiState.Success(resultString, computationDuration, stringConversionDuration)
34-
} catch (exception: Exception) {
35-
uiState.value = if (exception is CancellationException) {
36-
UiState.Error("Calculation was cancelled")
37-
} else {
38-
UiState.Error("Error while calculating result")
39-
}
40-
}
41-
}
4215
}
4316

44-
// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
45-
private suspend fun calculateFactorialOf(number: Int): BigInteger =
46-
withContext(defaultDispatcher) {
47-
var factorial = BigInteger.ONE
48-
for (i in 1..number) {
49-
50-
// yield enables cooperative cancellations
51-
// alternatives:
52-
// - ensureActive()
53-
// - isActive() - possible to do clean up tasks with
54-
yield()
55-
56-
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
57-
}
58-
factorial
59-
}
17+
fun cancelCalculation() {
6018

61-
private suspend fun convertToString(number: BigInteger): String =
62-
withContext(defaultDispatcher) {
63-
number.toString()
64-
}
19+
}
6520

6621
fun uiState(): LiveData<UiState> = uiState
6722

68-
fun cancelCalculation() {
69-
calculationJob?.cancel()
70-
}
71-
7223
private val uiState: MutableLiveData<UiState> = MutableLiveData()
7324
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase12
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
54
import kotlinx.coroutines.CoroutineDispatcher
65
import kotlinx.coroutines.Dispatchers
7-
import kotlinx.coroutines.launch
8-
import kotlinx.coroutines.withContext
9-
import java.math.BigInteger
10-
import kotlin.system.measureTimeMillis
116

127
class CalculationInSeveralCoroutinesViewModel(
138
private val factorialCalculator: FactorialCalculator = FactorialCalculator(),
@@ -18,32 +13,6 @@ class CalculationInSeveralCoroutinesViewModel(
1813
factorialOf: Int,
1914
numberOfCoroutines: Int
2015
) {
21-
uiState.value = UiState.Loading
22-
viewModelScope.launch {
2316

24-
var factorialResult = BigInteger.ZERO
25-
val computationDuration = measureTimeMillis {
26-
factorialResult =
27-
factorialCalculator.calculateFactorial(
28-
factorialOf,
29-
numberOfCoroutines
30-
)
31-
}
32-
33-
var resultString = ""
34-
val stringConversionDuration = measureTimeMillis {
35-
resultString = convertToString(factorialResult)
36-
}
37-
38-
uiState.value =
39-
UiState.Success(resultString, computationDuration, stringConversionDuration)
40-
}
4117
}
42-
43-
private suspend fun convertToString(
44-
number: BigInteger
45-
): String =
46-
withContext(defaultDispatcher) {
47-
number.toString()
48-
}
4918
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase13
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
54
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
65
import kotlinx.coroutines.*
@@ -11,59 +10,14 @@ class ExceptionHandlingViewModel(
1110
) : BaseViewModel<UiState>() {
1211

1312
fun handleExceptionWithTryCatch() {
14-
uiState.value = UiState.Loading
15-
viewModelScope.launch {
16-
try {
17-
api.getAndroidVersionFeatures(27)
1813

19-
} catch (exception: Exception) {
20-
uiState.value = UiState.Error("Network Request failed: $exception")
21-
}
22-
}
2314
}
2415

2516
fun handleWithCoroutineExceptionHandler() {
26-
val exceptionHandler = CoroutineExceptionHandler { _, exception ->
27-
uiState.value = UiState.Error("Network Request failed!! $exception")
28-
}
2917

30-
uiState.value = UiState.Loading
31-
viewModelScope.launch(exceptionHandler) {
32-
api.getAndroidVersionFeatures(27)
33-
}
3418
}
3519

3620
fun showResultsEvenIfChildCoroutineFails() {
37-
uiState.value = UiState.Loading
38-
viewModelScope.launch {
3921

40-
supervisorScope {
41-
val oreoFeaturesDeferred = async { api.getAndroidVersionFeatures(27) }
42-
val pieFeaturesDeferred = async { api.getAndroidVersionFeatures(28) }
43-
val android10FeaturesDeferred = async { api.getAndroidVersionFeatures(29) }
44-
45-
val versionFeatures = listOf(
46-
oreoFeaturesDeferred,
47-
pieFeaturesDeferred,
48-
android10FeaturesDeferred
49-
).mapNotNull {
50-
try {
51-
it.await()
52-
} catch (exception: Exception) {
53-
// We have to re-throw cancellation exceptions so that
54-
// our Coroutine gets cancelled immediately.
55-
// Otherwise, the CancellationException is ignored
56-
// and the Coroutine keeps running until it reaches the next
57-
// suspension point.
58-
if (exception is CancellationException) {
59-
throw exception
60-
}
61-
Timber.e("Error loading feature data!")
62-
null
63-
}
64-
}
65-
uiState.value = UiState.Success(versionFeatures)
66-
}
67-
}
6822
}
6923
}

app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/ContinueCoroutineWhenUserLeavesScreenViewModel.kt

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,17 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase14
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
5-
import kotlinx.coroutines.launch
64

75
class ContinueCoroutineWhenUserLeavesScreenViewModel(
86
private var repository: AndroidVersionRepository
97
) : BaseViewModel<UiState>() {
108

11-
// more information in this blogpost about "Coroutines & Patterns for work that shouldn't
12-
// be cancelled" =>
13-
// https://medium.com/androiddevelopers/coroutines-patterns-for-work-that-shouldnt-be-cancelled-e26c40f142ad
14-
159
fun loadData() {
16-
uiState.value = UiState.Loading.LoadFromDb
17-
18-
viewModelScope.launch {
19-
val localVersions = repository.getLocalAndroidVersions()
20-
if (localVersions.isNotEmpty()) {
21-
uiState.value =
22-
UiState.Success(DataSource.Database, localVersions)
23-
} else {
24-
uiState.value =
25-
UiState.Error(DataSource.Database, "Database empty!")
26-
}
2710

28-
uiState.value = UiState.Loading.LoadFromNetwork
29-
30-
try {
31-
uiState.value = UiState.Success(
32-
DataSource.Network,
33-
repository.loadAndStoreRemoteAndroidVersions()
34-
)
35-
} catch (exception: Exception) {
36-
uiState.value = UiState.Error(DataSource.Network, "Network Request failed")
37-
}
38-
}
3911
}
4012

4113
fun clearDatabase() {
42-
repository.clearDatabase()
14+
4315
}
4416
}
4517

Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
11
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
22

3-
import androidx.lifecycle.viewModelScope
43
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
54
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
6-
import kotlinx.coroutines.launch
75

86
class Perform2SequentialNetworkRequestsViewModel(
97
private val mockApi: MockApi = mockApi()
108
) : BaseViewModel<UiState>() {
119

1210
fun perform2SequentialNetworkRequest() {
13-
uiState.value = UiState.Loading
14-
viewModelScope.launch {
15-
try {
16-
val recentVersions = mockApi.getRecentAndroidVersions()
17-
val mostRecentVersion = recentVersions.last()
1811

19-
val featuresOfMostRecentVersion =
20-
mockApi.getAndroidVersionFeatures(mostRecentVersion.apiLevel)
21-
22-
uiState.value = UiState.Success(featuresOfMostRecentVersion)
23-
} catch (exception: Exception) {
24-
uiState.value = UiState.Error("Network Request failed")
25-
}
26-
}
2712
}
2813
}

0 commit comments

Comments
 (0)