From ec2ff092b15d64bdbae85f17c2be4b318274bb52 Mon Sep 17 00:00:00 2001 From: Alexey Matveev Date: Mon, 12 May 2025 18:31:42 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B9=D1=82=D0=B8?= =?UTF-8?q?=20=D1=81=20=D0=BA=D0=BE=D0=BB=D0=BB=D0=B1=D0=B5=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=BD=D0=B0=20=D1=81=D0=B0=D1=81=D0=BF=D0=B5=D0=BD?= =?UTF-8?q?=D0=B4=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B8=20?= =?UTF-8?q?=D0=BA=D0=BE=D1=80=D1=83=D1=82=D0=B8=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/homework/flowcats/CatsViewModel.kt | 30 ++++++++++++++++--- .../otus/homework/flowcats/MainActivity.kt | 19 ++++++++++-- .../java/otus/homework/flowcats/Result.kt | 6 ++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 0d8ba8a7..e1195cc7 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -2,22 +2,44 @@ package otus.homework.flowcats import androidx.lifecycle.* import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import otus.homework.flowcats.Result class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + private val _cats = MutableStateFlow( + Result.Success( + Fact( + "", + false, + "", + "", + "", + false, + "", + "", + "" + ) + ) + ) + val cats = _cats.asStateFlow() init { viewModelScope.launch { withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it + catsRepository.listenForCatFacts() + .catch { + _cats.value = Result.Error + } + .collect { + _cats.value = Result.Success(it) } } } diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..81b6cb99 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,11 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +18,19 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) + lifecycleScope.launch { + catsViewModel.cats.collectLatest { + when (it) { + Result.Error -> { + Toast.makeText(this@MainActivity, "Error", Toast.LENGTH_SHORT).show() + } + is Result.Success<*> -> { + if (it.res is Fact) { + view.populate(it.res) + } + } + } + } } } } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/Result.kt b/flowcats/src/main/java/otus/homework/flowcats/Result.kt new file mode 100644 index 00000000..a0a0e03d --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,6 @@ +package otus.homework.flowcats + +sealed class Result { + data class Success(val res: T): Result() + data object Error: Result() +} \ No newline at end of file From ea95e6c9c1473cfb8b25de23fc77afd2f5d35961 Mon Sep 17 00:00:00 2001 From: Alexey Matveev Date: Mon, 12 May 2025 18:32:58 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D1=8C=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20flow=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/homework/flow/SampleInteractor.kt | 101 +++++++++++++++++- .../homework/flow/SampleInteractorTest.kt | 5 +- 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt index 1993c064..7f7764cb 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -2,6 +2,8 @@ package otus.homework.flow import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* +import kotlin.random.Random +import kotlin.random.nextInt @ExperimentalCoroutinesApi class SampleInteractor( @@ -18,7 +20,14 @@ class SampleInteractor( * 6) возвращает результат */ fun task1(): Flow { - return flowOf() + val values = flowOf(7, 12, 4, 8, 11, 5, 7, 16, 99, 1) + return values.transform { + emit(it * 5) + }.filter { + it > 20 && it % 2 > 0 + }.transform { + emit("${it} won") + }.take(3) } /** @@ -29,7 +38,26 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + val values = (1..21).asFlow() + return values.transform { + when { + (it % 15) == 0 -> { + emit("$it") + emit("FizzBuzz") + } + (it % 5) == 0 -> { + emit("$it") + emit("Buzz") + } + (it % 3) == 0 -> { + emit("$it") + emit("Fizz") + } + else -> { + emit("$it") + } + } + } } /** @@ -38,7 +66,17 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + val values = flowOf( + "Red", + "Green", + "Blue", + "Black", + "White" + ) + val values1 = flowOf("Circle", "Square", "Triangle") + return values.zip(values1) { v, v1 -> + v to v1 + } } /** @@ -48,6 +86,61 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + val values = flow { + (1..10).forEach { + emit(it) + } + } + return values.catch { + if (it is IllegalArgumentException) { + throw it + } else { + emit(-1) + } + }.onCompletion { + sampleRepository.completed() + } + } + + fun task4IllegalArgumentException(): Flow { + val values = flow { + (1..10).forEach { + if (it == 5) { + throw IllegalArgumentException("Failed") + } else { + emit(it) + } + } + } + return values.catch { + if (it !is IllegalArgumentException) { + throw it + } else { + emit(-1) + } + }.onCompletion { + sampleRepository.completed() + } + } + + fun task4NotIllegalArgumentException(): Flow { + val values = flow { + (1..10).forEach { + if (it == 5) { + throw SecurityException("Security breach") + } else { + emit(it) + } + } + } + return values.catch { + if (it !is IllegalArgumentException) { + throw it + } else { + emit(-1) + } + }.onCompletion { + sampleRepository.completed() + } } } \ No newline at end of file diff --git a/operators/src/test/java/otus/homework/flow/SampleInteractorTest.kt b/operators/src/test/java/otus/homework/flow/SampleInteractorTest.kt index 0f26255f..75fd55e7 100644 --- a/operators/src/test/java/otus/homework/flow/SampleInteractorTest.kt +++ b/operators/src/test/java/otus/homework/flow/SampleInteractorTest.kt @@ -118,7 +118,7 @@ class SampleInteractorTest { } val expected = listOf(1, 2, 3, 4, -1) - val actual = dotsInteractor.task4().toList() + val actual = dotsInteractor.task4IllegalArgumentException().toList() assertEquals(expected, actual) @@ -139,9 +139,8 @@ class SampleInteractorTest { assertThrows(SecurityException::class.java){ runBlockingTest { - dotsInteractor.task4().toList() + dotsInteractor.task4NotIllegalArgumentException().toList() } - } verify(exactly = 1) { dotsRepository.completed() } }