diff --git a/flowcats/build.gradle b/flowcats/build.gradle index 0ea35e68..d0bc6703 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 33 versionCode 1 versionName "1.0" @@ -36,16 +36,17 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.core:core-ktx:1.13.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' - implementation 'com.google.code.gson:gson:2.8.6' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 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' - testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1' + implementation 'androidx.activity:activity-ktx:1.9.1' + implementation 'androidx.test.ext:junit-ktx:1.2.1' + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4' } \ 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..12ec6a70 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsRepository.kt @@ -1,18 +1,24 @@ package otus.homework.flowcats import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow +import otus.homework.flowcats.Result +import java.util.concurrent.TimeoutException class CatsRepository( private val catsService: CatsService, private val refreshIntervalMs: Long = 5000 ) { - fun listenForCatFacts() = flow { + fun listenForCatFacts() = flow { while (true) { val latestNews = catsService.getCatFact() - emit(latestNews) + emit(Result.Success(latestNews)) delay(refreshIntervalMs) } + }.catch { + println(it) + emit(Result.Error) } } \ 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..a2907d44 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/CatsViewModel.kt @@ -2,7 +2,8 @@ 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.launch import kotlinx.coroutines.withContext @@ -10,14 +11,14 @@ class CatsViewModel( private val catsRepository: CatsRepository ) : ViewModel() { - private val _catsLiveData = MutableLiveData() - val catsLiveData: LiveData = _catsLiveData + private val _catsFlow = MutableStateFlow(Result.Init) + val catsFlow: StateFlow = _catsFlow init { viewModelScope.launch { withContext(Dispatchers.IO) { catsRepository.listenForCatFacts().collect { - _catsLiveData.value = it + _catsFlow.value = it } } } @@ -26,6 +27,6 @@ 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 } \ 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..1339b65f 100644 --- a/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt +++ b/flowcats/src/main/java/otus/homework/flowcats/MainActivity.kt @@ -2,7 +2,13 @@ package otus.homework.flowcats import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels +import androidx.core.content.ContextCompat +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -14,8 +20,23 @@ 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 { + repeatOnLifecycle(Lifecycle.State.STARTED) { + catsViewModel.catsFlow.collect { result -> + when (result) { + is Result.Success<*> -> view.populate(result.data as Fact) + is Result.Error -> { + Toast.makeText( + this@MainActivity, + ContextCompat.getString(this@MainActivity, R.string.text_error), + Toast.LENGTH_SHORT + ).show() + } + + else -> {} + } + } + } } } } \ 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..748c482d --- /dev/null +++ b/flowcats/src/main/java/otus/homework/flowcats/Result.kt @@ -0,0 +1,7 @@ +package otus.homework.flowcats + +sealed class Result { + class Success(val data: T) : Result() + data object Error : Result() + data object Init : Result() +} diff --git a/flowcats/src/main/res/values/strings.xml b/flowcats/src/main/res/values/strings.xml index ba737b82..35a69b11 100644 --- a/flowcats/src/main/res/values/strings.xml +++ b/flowcats/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ Flow cats + Упс! Что-то пошло не так... \ 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..1ac8a239 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,15 @@ class SampleInteractor( * Если число не делится на 3,5,15 - эмитим само число */ fun task2(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .transform { + emit("$it") + when { + it % 15 == 0 -> emit("FizzBuzz") + it % 3 == 0 -> emit("Fizz") + it % 5 == 0 -> emit("Buzz") + } + } } /** @@ -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,10 @@ class SampleInteractor( * При любом исходе, будь то выброс исключения или успешная отработка функции вызовите метод dotsRepository.completed() */ fun task4(): Flow { - return flowOf() + return sampleRepository.produceNumbers() + .catch { + it.takeIf { it is IllegalArgumentException }?.let { emit(-1) } ?: run { throw it } + } + .onCompletion { sampleRepository.completed() } } -} \ No newline at end of file +}