From 17591a79665c255e5bea423ea0f6398467adc4fb Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:28:45 +0300 Subject: [PATCH 1/7] values --- app/src/main/java/otus/homework/reactivecats/Values.kt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/java/otus/homework/reactivecats/Values.kt diff --git a/app/src/main/java/otus/homework/reactivecats/Values.kt b/app/src/main/java/otus/homework/reactivecats/Values.kt new file mode 100644 index 00000000..7efba2a9 --- /dev/null +++ b/app/src/main/java/otus/homework/reactivecats/Values.kt @@ -0,0 +1,3 @@ +package otus.homework.reactivecats + +const val timeout = 2000L \ No newline at end of file From 457867690eeb4e92dcbe0cdad0d2d87f5eb9fc47 Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:32:17 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B2=D0=B5=D0=B4?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=20=D1=81=D0=B5=D1=82=D0=B5=D0=B2=D0=BE=D0=B9?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20=D1=81=20retrofit.Cal?= =?UTF-8?q?l=20=D0=BD=D0=B0=20RX=20=D1=86=D0=B5=D0=BF=D0=BE=D1=87=D0=BA?= =?UTF-8?q?=D1=83.=20=D0=94=D0=BB=D1=8F=20=D1=8D=D1=82=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=20Retrofit=20=D0=B0=D0=B4=D0=B0=D0=BF=D1=82=D0=B5=D1=80,=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=B9=D1=82=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D0=BC=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B8=D0=BF=D1=8B=20=D1=84=D1=83=D0=BD=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/otus/homework/reactivecats/CatsService.kt | 3 ++- app/src/main/java/otus/homework/reactivecats/DiContainer.kt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/otus/homework/reactivecats/CatsService.kt b/app/src/main/java/otus/homework/reactivecats/CatsService.kt index c79be483..52626c78 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsService.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsService.kt @@ -1,10 +1,11 @@ package otus.homework.reactivecats +import io.reactivex.Single import retrofit2.Call import retrofit2.http.GET interface CatsService { @GET("random?animal_type=cat") - fun getCatFact(): Call + fun getCatFact(): Single } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/reactivecats/DiContainer.kt b/app/src/main/java/otus/homework/reactivecats/DiContainer.kt index dfbb9a2b..ad1aa751 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/") .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build() } From 85887df2a11ba6a8127cc39b0f7aa80bf9d0d4ad Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:34:33 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=B9?= =?UTF-8?q?=D1=82=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D0=B2=20?= =?UTF-8?q?CatsViewModel.kt=20=D1=81=20=D0=BA=D0=BE=D0=BB=D0=B1=D0=B5?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2=20=D0=BD=D0=B0=20RX.=20=D0=9B=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BA=D1=83=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=83=D1=81=D0=BF=D0=B5=D1=85=D0=B0/=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=B8=D0=B7=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BB=D0=BB=D0=B1=D0=B5=D0=BA=D0=B0=20=D0=BD=D0=B5=D0=BE=D0=B1?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20=D0=B2=20=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=BC=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=D0=B1=D0=B5=D0=BA=D0=B8=20RX=20=D1=86=D0=B5?= =?UTF-8?q?=D0=BF=D0=BE=D1=87=D0=BA=D0=B8.=20=D0=9D=D0=B5=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B1=D1=83=D0=B4=D1=8C=D1=82=D0=B5=20=D0=BE=D1=87=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20ViewModel=20?= =?UTF-8?q?=D1=83=D0=BD=D0=B8=D1=87=D1=82=D0=BE=D0=B6=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework/reactivecats/CatsViewModel.kt | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt index d62eaf97..f6b7533c 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt @@ -1,44 +1,69 @@ package otus.homework.reactivecats +import android.annotation.SuppressLint import android.content.Context 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.FlowableEmitter +import io.reactivex.FlowableSubscriber +import io.reactivex.Observable +import io.reactivex.ObservableOnSubscribe +import io.reactivex.Observer +import io.reactivex.SingleObserver +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.disposables.Disposable +import io.reactivex.schedulers.Schedulers +import org.reactivestreams.Subscription +import retrofit2.HttpException +import java.util.concurrent.TimeUnit class CatsViewModel( - catsService: CatsService, - localCatFactsGenerator: LocalCatFactsGenerator, + private val catsService: CatsService, + private val localCatFactsGenerator: LocalCatFactsGenerator, context: Context ) : ViewModel() { + private val error = context.getString( + R.string.default_error_text + ) private val _catsLiveData = MutableLiveData() val catsLiveData: LiveData = _catsLiveData + private val compositeDisposable = CompositeDisposable() + + private fun init() { + compositeDisposable.add( + catsService.getCatFact().toObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { n -> + _catsLiveData.value = Success(n) + }, { e -> + if (e is HttpException) { + _catsLiveData.value = Error(e.message ?: error) + } else { + _catsLiveData.value = ServerError + } + }, {}, {} + ) + ) + } 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 - ) - ) - } - } - - override fun onFailure(call: Call, t: Throwable) { - _catsLiveData.value = ServerError - } - }) + init() +// getFacts() } fun getFacts() {} + + override fun onCleared() { + if (!compositeDisposable.isDisposed) { + compositeDisposable.dispose() + } + } } class CatsViewModelFactory( From b6022f0066ae2b5f5761f453dc70c438a3ae1102 Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:37:40 +0300 Subject: [PATCH 4/7] random facts generator function --- .../java/otus/homework/reactivecats/LocalCatFactsGenerator.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index 4481062e..a8bc846c 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -9,6 +9,7 @@ class LocalCatFactsGenerator( private val context: Context ) { + private fun _generateCatFact() = Fact(context.resources.getStringArray(R.array.local_cat_facts)[Random.nextInt(5)]) /** * Реализуйте функцию otus.homework.reactivecats.LocalCatFactsGenerator#generateCatFact так, * чтобы она возвращала Fact со случайной строкой из массива строк R.array.local_cat_facts From 3ef27f3647584759d0b0b2769818ad70cb7e88d7 Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:42:19 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D1=83?= =?UTF-8?q?=D0=B9=D1=82=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20otus.homework.reactivecats.LocalCatFactsGenerator#generateCa?= =?UTF-8?q?tFact,=20=D1=82=D0=B0=D0=BA,=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=20=D0=BE=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=89=D0=B0=D0=BB=D0=B0=20Fact=20=D1=81=D0=BE=20=D1=81=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B0=D0=B9=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=B9=20=D0=B8=D0=B7=20=D0=BC=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D0=B8=D0=B2=D0=B0=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=20R.a?= =?UTF-8?q?rray.local=5Fcat=5Ffacts=20=D0=BE=D0=B1=D0=B5=D1=80=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D1=83=D1=8E=20=D0=B2=20=D0=BF=D0=BE=D0=B4=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D1=8F=D1=89=D0=B8=D0=B9=20=D1=81=D1=82=D1=80=D0=B8=D0=BC?= =?UTF-8?q?(Flowable/Single/Observable=20=D0=B8=20=D1=82.=D0=BF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/homework/reactivecats/LocalCatFactsGenerator.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index a8bc846c..bcb1328e 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -2,7 +2,11 @@ package otus.homework.reactivecats import android.content.Context import io.reactivex.Flowable +import io.reactivex.Observable +import io.reactivex.Observer import io.reactivex.Single +import io.reactivex.SingleOnSubscribe +import java.util.concurrent.TimeUnit import kotlin.random.Random class LocalCatFactsGenerator( @@ -10,13 +14,14 @@ class LocalCatFactsGenerator( ) { private fun _generateCatFact() = Fact(context.resources.getStringArray(R.array.local_cat_facts)[Random.nextInt(5)]) + /** * Реализуйте функцию otus.homework.reactivecats.LocalCatFactsGenerator#generateCatFact так, * чтобы она возвращала Fact со случайной строкой из массива строк R.array.local_cat_facts * обернутую в подходящий стрим(Flowable/Single/Observable и т.п) */ fun generateCatFact(): Single { - return Single.never() + return Single.just(_generateCatFact()) } /** From 0c011802060c7496c78f8c40cdc9205e5f267c47 Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:46:21 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D1=83?= =?UTF-8?q?=D0=B9=D1=82=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20otus.homework.reactivecats.LocalCatFactsGenerator#generateCa?= =?UTF-8?q?tFactPeriodically=20=D1=82=D0=B0=D0=BA,=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=20=D0=BE=D0=BD=D0=B0=20=D1=8D=D0=BC=D0=B8=D1=82?= =?UTF-8?q?=D0=B8=D0=BB=D0=B0=20Fact=20=D1=81=D0=BE=20=D1=81=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D0=B0=D0=B9=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BA=D0=BE=D0=B9=20=D0=B8=D0=B7=20=D0=BC=D0=B0=D1=81=D1=81?= =?UTF-8?q?=D0=B8=D0=B2=D0=B0=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=20R.array.l?= =?UTF-8?q?ocal=5Fcat=5Ffacts=20=D0=BA=D0=B0=D0=B6=D0=B4=D1=8B=D0=B5=20200?= =?UTF-8?q?0=20=D0=BC=D0=B8=D0=BB=D0=BB=D0=B8=D1=81=D0=B5=D0=BA=D1=83?= =?UTF-8?q?=D0=BD=D0=B4.=20=D0=95=D1=81=D0=BB=D0=B8=20=D0=B2=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D1=8C=20=D0=B7=D0=B0=D1=8D=D0=BC=D0=B8=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20Fact=20=D1=81=D0=BE=D0=B2=D0=BF=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D0=B5=D1=82=20=D1=81=20=D0=BF=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D1=8B=D0=B4=D1=83=D1=89=D0=B8=D0=BC=20-=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D0=B5=D0=BC=20=D1=8D=D0=BB=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otus/homework/reactivecats/LocalCatFactsGenerator.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index bcb1328e..4d8ecfa8 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -30,7 +30,8 @@ class LocalCatFactsGenerator( * Если вновь заэмиченный Fact совпадает с предыдущим - пропускаем элемент. */ fun generateCatFactPeriodically(): Flowable { - val success = Fact(context.resources.getStringArray(R.array.local_cat_facts)[Random.nextInt(5)]) - return Flowable.empty() + return Flowable.concat(Flowable.just(_generateCatFact()), Flowable.interval(timeout, TimeUnit.MILLISECONDS).flatMap { + Flowable.just(_generateCatFact()) + }).distinctUntilChanged().onBackpressureLatest() } } \ No newline at end of file From 4fecae74da11e941713baa22eee1a99c060c9f26 Mon Sep 17 00:00:00 2001 From: mtv26 Date: Tue, 15 Apr 2025 13:46:50 +0300 Subject: [PATCH 7/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D1=83?= =?UTF-8?q?=D0=B9=D1=82=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20otus.homework.reactivecats.CatsViewModel#getFacts=20=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D0=BC=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=BE=D0=BC:=20=D0=BA=D0=B0=D0=B6=D0=B4?= =?UTF-8?q?=D1=8B=D0=B5=202=20=D1=81=D0=B5=D0=BA=D1=83=D0=BD=D0=B4=D1=8B?= =?UTF-8?q?=20=D0=B8=D0=B4=D0=B5=D0=BC=20=D0=B2=20=D1=81=D0=B5=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B7=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=BC=20=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D0=BC,=20=D0=B5=D1=81=D0=BB=D0=B8=20=D1=81?= =?UTF-8?q?=D0=B5=D1=82=D0=B5=D0=B2=D0=BE=D0=B9=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=20=D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F=20=D0=BD=D0=B5=D1=83=D1=81=D0=BF=D0=B5=D1=88=D0=BD?= =?UTF-8?q?=D0=BE,=20=D1=82=D0=BE=20=D0=B2=20=D0=BA=D0=B0=D1=87=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B5=20=D1=84=D0=BE=D0=BB=D0=BB=D0=B1=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B8=D0=B4=D0=B5=D0=BC=20=D0=B7=D0=B0=20=D1=84?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=BE=D0=BC=20=D0=B2=20=D1=83=D0=B6=D0=B5=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20otus.homework.reactivecats.LocalCatFactsGe?= =?UTF-8?q?nerator#generateCatFact.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework/reactivecats/CatsViewModel.kt | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt index f6b7533c..538fade5 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt @@ -57,7 +57,27 @@ class CatsViewModel( // getFacts() } - fun getFacts() {} + fun getFacts() { + compositeDisposable.add( + Observable.interval(timeout, TimeUnit.MILLISECONDS).flatMapSingle { + catsService.getCatFact() + }.onErrorResumeNext ( + localCatFactsGenerator.generateCatFact().toObservable() + ).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { n -> + _catsLiveData.value = Success(n) + }, { e -> + if (e is HttpException) { + _catsLiveData.value = Error(e.message ?: error) + } else { + _catsLiveData.value = ServerError + } + }, {}, {} + ) + ) + } override fun onCleared() { if (!compositeDisposable.isDisposed) {