From 6f7feab5db90b9a5e39dc335159acc66b130a058 Mon Sep 17 00:00:00 2001 From: Dmitry Ryaboshapko Date: Sun, 18 Jan 2026 11:43:21 +0300 Subject: [PATCH] =?UTF-8?q?HomeWork=20-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20RxJava2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 + .../otus/homework/reactivecats/CatsService.kt | 3 +- .../homework/reactivecats/CatsViewModel.kt | 66 ++++++++++++------- .../otus/homework/reactivecats/DiContainer.kt | 2 + .../reactivecats/LocalCatFactsGenerator.kt | 12 +++- .../homework/reactivecats/MainActivity.kt | 6 ++ gradle/libs.versions.toml | 2 + 7 files changed, 67 insertions(+), 27 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4a3a24af..70d5ff22 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,4 +47,7 @@ dependencies { implementation libs.picasso implementation libs.rxjava implementation libs.rxandroid + implementation libs.rx.android.adapter + implementation libs.retrofit + implementation libs.retrofit.converter.gson } diff --git a/app/src/main/java/otus/homework/reactivecats/CatsService.kt b/app/src/main/java/otus/homework/reactivecats/CatsService.kt index f30b3aac..e98252f6 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsService.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsService.kt @@ -1,5 +1,6 @@ package otus.homework.reactivecats +import io.reactivex.Single import retrofit2.Call import retrofit2.http.GET @@ -7,5 +8,5 @@ interface CatsService { //@GET("random?animal_type=cat") @GET("fact") - fun getCatFact(): Call + fun getCatFact(): Single } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt index d62eaf97..86812184 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt @@ -1,44 +1,62 @@ package otus.homework.reactivecats import android.content.Context +import android.content.res.Resources import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import io.reactivex.Flowable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import java.util.concurrent.TimeUnit class CatsViewModel( - catsService: CatsService, - localCatFactsGenerator: LocalCatFactsGenerator, - context: Context + private val catsService: CatsService, + private val localCatFactsGenerator: LocalCatFactsGenerator, + private val resource: Resources ) : ViewModel() { + private val disposable: CompositeDisposable = CompositeDisposable() + private val _catsLiveData = MutableLiveData() val catsLiveData: LiveData = _catsLiveData - init { - catsService.getCatFact().enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful && response.body() != null) { - _catsLiveData.value = Success(response.body()!!) - } else { - _catsLiveData.value = Error( - response.errorBody()?.string() ?: context.getString( - R.string.default_error_text - ) - ) + fun getFacts() { + disposable.add( + Flowable.interval(0,2000, TimeUnit.MILLISECONDS) + .subscribeOn(Schedulers.io()) + .flatMapSingle { + catsService + .getCatFact() + .subscribeOn(Schedulers.io()) + .onErrorResumeNext { + localCatFactsGenerator.generateCatFact() + } } - } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(::success, ::error) + ) + } + + fun onDestroy() { + disposable.clear() + } + + private fun success(fact: Fact) { + _catsLiveData.value = Success(fact) + } - override fun onFailure(call: Call, t: Throwable) { - _catsLiveData.value = ServerError - } - }) + private fun error(error: Throwable) { + Error( + error.message ?: resource.getString( + R.string.default_error_text + ) + ) } - fun getFacts() {} + } class CatsViewModelFactory( @@ -49,7 +67,7 @@ class CatsViewModelFactory( ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T = - CatsViewModel(catsRepository, localCatFactsGenerator, context) as T + CatsViewModel(catsRepository, localCatFactsGenerator, context.resources) as T } sealed class Result diff --git a/app/src/main/java/otus/homework/reactivecats/DiContainer.kt b/app/src/main/java/otus/homework/reactivecats/DiContainer.kt index bbccfc7b..c018bca7 100644 --- a/app/src/main/java/otus/homework/reactivecats/DiContainer.kt +++ b/app/src/main/java/otus/homework/reactivecats/DiContainer.kt @@ -2,6 +2,7 @@ package otus.homework.reactivecats import android.content.Context import retrofit2.Retrofit +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory import retrofit2.converter.gson.GsonConverterFactory class DiContainer { @@ -10,6 +11,7 @@ class DiContainer { Retrofit.Builder() //.baseUrl("https://cat-fact.herokuapp.com/facts/") .baseUrl("https://catfact.ninja/") + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() } diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index 4481062e..0bd893c7 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -3,6 +3,7 @@ package otus.homework.reactivecats import android.content.Context import io.reactivex.Flowable import io.reactivex.Single +import java.util.concurrent.TimeUnit import kotlin.random.Random class LocalCatFactsGenerator( @@ -15,7 +16,10 @@ class LocalCatFactsGenerator( * обернутую в подходящий стрим(Flowable/Single/Observable и т.п) */ fun generateCatFact(): Single { - return Single.never() + val strings = context.resources.getStringArray(R.array.local_cat_facts) + return Single.fromCallable { + (Fact(strings.random())) + } } /** @@ -25,6 +29,10 @@ class LocalCatFactsGenerator( */ fun generateCatFactPeriodically(): Flowable { val success = Fact(context.resources.getStringArray(R.array.local_cat_facts)[Random.nextInt(5)]) - return Flowable.empty() + return Flowable.interval(0,2, TimeUnit.MILLISECONDS) + .map { + success + } + .distinctUntilChanged() } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/reactivecats/MainActivity.kt b/app/src/main/java/otus/homework/reactivecats/MainActivity.kt index 8ec95711..1a3a591c 100644 --- a/app/src/main/java/otus/homework/reactivecats/MainActivity.kt +++ b/app/src/main/java/otus/homework/reactivecats/MainActivity.kt @@ -22,6 +22,7 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) + catsViewModel.getFacts() catsViewModel.catsLiveData.observe(this) { result -> when (result) { is Success -> view.populate(result.fact) @@ -30,4 +31,9 @@ class MainActivity : AppCompatActivity() { } } } + + override fun onDestroy() { + catsViewModel.onDestroy() + super.onDestroy() + } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 46c95785..d3d04d37 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ picasso = "2.71828" retrofit = "2.9.0" rxandroid = "2.1.1" rxjava = "2.2.21" +rx-adapter = "3.0.0" [libraries] core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } @@ -32,6 +33,7 @@ picasso = { module = "com.squareup.picasso:picasso", version.ref = "picasso" } retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" } rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroid" } +rx-android-adapter = { module = "com.squareup.retrofit2:adapter-rxjava2", version.ref = "rx-adapter" } rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava" } [bundles]