From fdf215626a09f1f94aa25897aa71d018d3282bb5 Mon Sep 17 00:00:00 2001 From: Beknur Patsaev Date: Sun, 2 Feb 2025 00:45:29 +0300 Subject: [PATCH 1/4] =?UTF-8?q?1.=20=D0=A1=D0=B5=D0=B9=D1=87=D0=B0=D1=81?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BA=D1=80=D0=B0=D1=88=D0=B8=D1=82=D1=81=D1=8F.=20=D0=9F?= =?UTF-8?q?=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D1=8C=D1=82=D0=B5=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BA=D1=83.=20-=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BB=20=D1=81=D0=B5=D1=82=D0=B8=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B2=20LiveData=20=D0=BD=D0=B0=20IO=20=D0=B4=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D0=B0=D1=82=D1=87=D0=B5=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/otus/homework/flowcats/CatsViewModel.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 0d8ba8a7..636df360 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -3,6 +3,8 @@ package otus.homework.flowcats import androidx.lifecycle.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.produceIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -15,17 +17,17 @@ class CatsViewModel( init { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { + catsRepository.listenForCatFacts() + .flowOn(Dispatchers.IO) + .collect { _catsLiveData.value = it } - } } } } class CatsViewModelFactory(private val catsRepository: CatsRepository) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T = + override fun create(modelClass: Class): T = CatsViewModel(catsRepository) as T } \ No newline at end of file From 99261cb7246665b402cc915797382083baac3d7c Mon Sep 17 00:00:00 2001 From: Beknur Patsaev Date: Sun, 2 Feb 2025 01:05:43 +0300 Subject: [PATCH 2/4] =?UTF-8?q?2.=20=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=B9=D1=82=D0=B5=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8E=20=D1=81=20`LiveData`=20=D0=BD=D0=B0=20`Stat?= =?UTF-8?q?eFlow`=20-=20=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B5=D1=89=D0=B5=20=D0=BB=D0=B8=D0=B1=D1=83,=20?= =?UTF-8?q?=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=B5=D0=B5?= =?UTF-8?q?=20=D1=81=D0=BA=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=82=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D1=84=D0=BB=D0=BE=D1=83=20=D0=B2=20=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D0=B2=D0=B8=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flowcats/build.gradle | 1 + .../main/java/otus/homework/flowcats/CatsViewModel.kt | 11 ++++++----- .../main/java/otus/homework/flowcats/MainActivity.kt | 10 ++++++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/flowcats/build.gradle b/flowcats/build.gradle index 0ea35e68..e0733d47 100644 --- a/flowcats/build.gradle +++ b/flowcats/build.gradle @@ -48,4 +48,5 @@ dependencies { implementation 'androidx.activity:activity-ktx:1.2.3' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 636df360..46a1c6c3 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -2,25 +2,26 @@ package otus.homework.flowcats import androidx.lifecycle.* import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.produceIn import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + private val _catsStateFlow = MutableStateFlow(null) + val catsStateFlow: StateFlow = _catsStateFlow.asStateFlow() init { viewModelScope.launch { catsRepository.listenForCatFacts() .flowOn(Dispatchers.IO) .collect { - _catsLiveData.value = it + _catsStateFlow.value = 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..88adb8f9 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -3,6 +3,10 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.viewModels +import androidx.lifecycle.flowWithLifecycle +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +18,10 @@ 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.catsStateFlow.flowWithLifecycle(lifecycle).collectLatest { fact -> + fact?.let { view.populate(it) } + } } } } \ No newline at end of file From 3519335bc51b295a24075d2366747a6915c32f18 Mon Sep 17 00:00:00 2001 From: Beknur Patsaev Date: Sun, 2 Feb 2025 01:33:46 +0300 Subject: [PATCH 3/4] =?UTF-8?q?3.=20=D0=92=20=D1=81=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D0=B0=D0=B5=20=D0=B5=D1=81=D0=BB=D0=B8=20=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=BD=D0=B8=D0=BA=D0=BD=D0=B5=D1=82=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=20=D1=81=D1=82=D1=80=D0=B8=D0=BC=D0=B5,?= =?UTF-8?q?=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=20=D0=B7=D0=B0=D1=8D=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D0=B8=D1=82=D1=8C=20=D0=B0=D0=B9=D1=82=D0=B5=D0=BC?= =?UTF-8?q?=20`Result.Error`*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flowcats/build.gradle | 2 +- .../java/otus/homework/flowcats/CatsViewModel.kt | 8 +++++--- .../java/otus/homework/flowcats/MainActivity.kt | 13 +++++++++++-- .../src/main/java/otus/homework/flowcats/Result.kt | 6 ++++++ 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 flowcats/src/main/java/otus/homework/flowcats/Result.kt diff --git a/flowcats/build.gradle b/flowcats/build.gradle index e0733d47..66bd4fe0 100644 --- a/flowcats/build.gradle +++ b/flowcats/build.gradle @@ -4,7 +4,7 @@ plugins { } android { - compileSdkVersion 30 + compileSdkVersion 34 buildToolsVersion "30.0.3" namespace = "otus.homework.flowcats" diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt index 46a1c6c3..bd9d3c2b 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch @@ -13,15 +14,16 @@ class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsStateFlow = MutableStateFlow(null) - val catsStateFlow: StateFlow = _catsStateFlow.asStateFlow() + private val _catsStateFlow = MutableStateFlow(null) + val catsStateFlow: StateFlow = _catsStateFlow.asStateFlow() init { viewModelScope.launch { catsRepository.listenForCatFacts() .flowOn(Dispatchers.IO) + .catch { _catsStateFlow.value = Result.Error(it.message.toString()) } .collect { - _catsStateFlow.value = it + _catsStateFlow.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 88adb8f9..9cfa21fc 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,6 +2,7 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope @@ -19,8 +20,16 @@ class MainActivity : AppCompatActivity() { setContentView(view) lifecycleScope.launch { - catsViewModel.catsStateFlow.flowWithLifecycle(lifecycle).collectLatest { fact -> - fact?.let { view.populate(it) } + catsViewModel.catsStateFlow.flowWithLifecycle(lifecycle).collectLatest { update -> + update?.let { result -> + when (result) { + is Result.Error -> { Toast.makeText(this@MainActivity, result.msg, Toast.LENGTH_SHORT).show() } + is Result.Success<*> -> { + val fact = result.result as? Fact + fact?.let { view.populate(it) } + } + } + } } } } 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..a9fa3456 --- /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 result: T) : Result() + data class Error(val msg: String) : Result() +} \ No newline at end of file From 613c5f70d4506a6fe320ab7b16481df0cd973b01 Mon Sep 17 00:00:00 2001 From: Beknur Patsaev Date: Sun, 2 Feb 2025 02:24:29 +0300 Subject: [PATCH 4/4] =?UTF-8?q?4.=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20flow=20=D0=BE?= =?UTF-8?q?=D0=BF=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 | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 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..be2dd6f2 100644 --- a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt +++ b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt @@ -18,7 +18,12 @@ class SampleInteractor( * 6) возвращает результат */ fun task1(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .map { it * 5 } + .filter { it > 20 } + .filter { it % 2 != 0 } + .map { "$it won" } + .take(3) } /** @@ -29,7 +34,25 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .transform { + when { + it % 15 == 0 -> { + emit(it.toString()) + emit("FizzBuzz") + } + + it % 3 == 0 -> { + emit(it.toString()) + emit("Fizz") + } + it % 5 == 0 -> { + emit(it.toString()) + emit("Buzz") + } + else -> emit(it.toString()) + } + } } /** @@ -38,7 +61,9 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return sampleRepository.produceColors().zip(sampleRepository.produceForms()) { color, form -> + Pair(color, form) + } } /** @@ -48,6 +73,8 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers().catch { + if (it is IllegalArgumentException) emit(-1) else throw it + }.onCompletion { sampleRepository.completed() } } } \ No newline at end of file