From 2fb7d49f23faceba7755379c2118b951095ad498 Mon Sep 17 00:00:00 2001 From: Valerii Mirhaydarov Date: Sat, 31 May 2025 14:27:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BE=D0=BC=D0=B0=D1=88=D0=BD=D0=B5?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20Flo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flowcats/build.gradle | 7 ++-- flowcats/src/main/AndroidManifest.xml | 3 +- .../otus/homework/flowcats/CatsRepository.kt | 4 ++- .../otus/homework/flowcats/CatsViewModel.kt | 28 +++++++++------ .../otus/homework/flowcats/MainActivity.kt | 34 +++++++++++++++++-- .../otus/homework/flow/SampleInteractor.kt | 34 ++++++++++++++++--- 6 files changed, 90 insertions(+), 20 deletions(-) diff --git a/flowcats/build.gradle b/flowcats/build.gradle index 0ea35e68..542a7644 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" @@ -12,7 +12,7 @@ android { defaultConfig { applicationId "otus.homework.flowcats" minSdkVersion 23 - targetSdkVersion 30 + targetSdkVersion 34 versionCode 1 versionName "1.0" @@ -46,6 +46,9 @@ dependencies { implementation 'com.squareup.picasso:picasso:2.71828' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3' implementation 'androidx.activity:activity-ktx:1.2.3' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' + + implementation 'androidx.lifecycle:lifecycle-viewmodel-android:2.8.6' } \ No newline at end of file diff --git a/flowcats/src/main/AndroidManifest.xml b/flowcats/src/main/AndroidManifest.xml index 2deb6454..6531e25f 100644 --- a/flowcats/src/main/AndroidManifest.xml +++ b/flowcats/src/main/AndroidManifest.xml @@ -10,7 +10,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Flow" > - + diff --git a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt index 10fcb77d..09c16e29 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt @@ -1,7 +1,9 @@ package otus.homework.flowcats +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn class CatsRepository( private val catsService: CatsService, @@ -14,5 +16,5 @@ class CatsRepository( emit(latestNews) delay(refreshIntervalMs) } - } + }.flowOn(Dispatchers.IO) } \ 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 0d8ba8a7..99bbab12 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -1,24 +1,26 @@ package otus.homework.flowcats import androidx.lifecycle.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow 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 _catsData = MutableStateFlow(Result.Empty) + val catsData: StateFlow = _catsData.asStateFlow() - init { + fun init() { viewModelScope.launch { - withContext(Dispatchers.IO) { - catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it + try { + catsRepository.listenForCatFacts().collect { fact -> + _catsData.value = Result.Success(fact) } + } catch (e: Exception) { + _catsData.value = Result.Error("Error: " + e.message) } } } @@ -26,6 +28,12 @@ class CatsViewModel( class CatsViewModelFactory(private val catsRepository: CatsRepository) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T = + override fun create(modelClass: Class): T = CatsViewModel(catsRepository) as T +} + +sealed class Result() { + data class Error(val message: String) : Result() + data class Success(val result: T) : Result() + object Empty : Result() } \ No newline at end of file diff --git a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt index edea434b..33c389b3 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,12 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +19,33 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsViewModel.catsLiveData.observe(this){ - view.populate(it) + catsViewModel.init() + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + catsViewModel.catsData.collect { result -> + when (result) { + is Result.Success<*> -> { + val fact = result.result as Fact + view.populate(fact) + } + is Result.Error -> { + Toast.makeText( + this@MainActivity, + result.message, + Toast.LENGTH_LONG + ).show() + } + Result.Empty -> { + Toast.makeText( + this@MainActivity, + "Empty Result", + Toast.LENGTH_LONG + ).show() + } + } + } + } } } } \ No newline at end of file diff --git a/operators/src/main/java/otus/homework/flow/SampleInteractor.kt b/operators/src/main/java/otus/homework/flow/SampleInteractor.kt index 1993c064..a42a16fb 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 } // Умножаем на 5 + .filter { it > 20 } // Фильтруем числа > 20 + .filter { it % 2 != 0 } // Убираем четные числа + .map { "$it won" } // Добавляем постфикс + .take(3) // Берем первые 3 элемента } /** @@ -29,7 +34,15 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .transform { number -> + emit(number.toString()) + when { + number % 15 == 0 -> emit("FizzBuzz") + number % 5 == 0 -> emit("Buzz") + number % 3 == 0 -> emit("Fizz") + } + } } /** @@ -38,7 +51,10 @@ class SampleInteractor( * Если айтемы в одно из флоу кончились то результирующий флоу также должен закончится */ fun task3(): Flow> { - return flowOf() + return sampleRepository.produceColors() + .zip(sampleRepository.produceForms()) { color, form -> + Pair(color, form) + } } /** @@ -48,6 +64,16 @@ 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