diff --git a/app/build.gradle b/app/build.gradle index 71df92dd..90d9c6fa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,4 +46,8 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0' implementation "io.reactivex.rxjava2:rxjava:2.2.21" implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + + implementation "io.reactivex.rxjava2:rxjava:2.2.21" + implementation "io.reactivex.rxjava2:rxandroid:2.1.1" + implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0" } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/reactivecats/CatsService.kt b/app/src/main/java/otus/homework/reactivecats/CatsService.kt index c79be483..dccdfdeb 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsService.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsService.kt @@ -1,10 +1,10 @@ package otus.homework.reactivecats -import retrofit2.Call +import io.reactivex.Single import retrofit2.http.GET interface CatsService { @GET("random?animal_type=cat") - fun getCatFact(): Call -} \ No newline at end of file + fun getCatFact(): Single +} diff --git a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt index d62eaf97..46fde314 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt @@ -5,40 +5,48 @@ 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 java.util.concurrent.TimeUnit + +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import io.reactivex.android.schedulers.AndroidSchedulers class CatsViewModel( - catsService: CatsService, - localCatFactsGenerator: LocalCatFactsGenerator, - context: Context + private val catsService: CatsService, + private val localCatFactsGenerator: LocalCatFactsGenerator, + private val context: Context ) : ViewModel() { + private val disposables = 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 - ) - ) - } - } + getFacts() + } - override fun onFailure(call: Call, t: Throwable) { - _catsLiveData.value = ServerError + fun getFacts() { + val subscription = Flowable.interval(2, TimeUnit.SECONDS) + .flatMapSingle { catsService.getCatFact() + .onErrorResumeNext { + localCatFactsGenerator.generateCatFact() + } } - }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { fact -> _catsLiveData.value = Success(fact) }, + { error -> _catsLiveData.value = Error(error.message ?: context.getString(R.string.default_error_text)) } + ) + disposables.add(subscription) } - fun getFacts() {} + override fun onCleared() { + super.onCleared() + disposables.clear() + } } class CatsViewModelFactory( @@ -55,4 +63,4 @@ class CatsViewModelFactory( sealed class Result data class Success(val fact: Fact) : Result() data class Error(val message: String) : Result() -object ServerError : Result() \ No newline at end of file +object ServerError : Result() diff --git a/app/src/main/java/otus/homework/reactivecats/DiContainer.kt b/app/src/main/java/otus/homework/reactivecats/DiContainer.kt index dfbb9a2b..224e9bfc 100644 --- a/app/src/main/java/otus/homework/reactivecats/DiContainer.kt +++ b/app/src/main/java/otus/homework/reactivecats/DiContainer.kt @@ -4,16 +4,19 @@ import android.content.Context import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory + class DiContainer { private val retrofit by lazy { Retrofit.Builder() .baseUrl("https://cat-fact.herokuapp.com/facts/") .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 🎯 ДобавляСм Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ RxJava .build() } val service by lazy { retrofit.create(CatsService::class.java) } fun localCatFactsGenerator(context: Context) = LocalCatFactsGenerator(context) -} \ No newline at end of file +} diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index 4481062e..c8322c8d 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -3,28 +3,25 @@ package otus.homework.reactivecats import android.content.Context import io.reactivex.Flowable import io.reactivex.Single +import io.reactivex.schedulers.Schedulers +import java.util.concurrent.TimeUnit import kotlin.random.Random class LocalCatFactsGenerator( private val context: Context ) { - /** - * Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ otus.homework.reactivecats.LocalCatFactsGenerator#generateCatFact Ρ‚Π°ΠΊ, - * Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π»Π° Fact со случайной строкой ΠΈΠ· массива строк R.array.local_cat_facts - * ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡƒΡŽ Π² подходящий стрим(Flowable/Single/Observable ΠΈ Ρ‚.ΠΏ) - */ fun generateCatFact(): Single { - return Single.never() + val factsArray = context.resources.getStringArray(R.array.local_cat_facts) + val randomFact = factsArray[Random.nextInt(factsArray.size)] + return Single.just(Fact(randomFact)) } - /** - * Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ otus.homework.reactivecats.LocalCatFactsGenerator#generateCatFactPeriodically Ρ‚Π°ΠΊ, - * Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° эмитила Fact со случайной строкой ΠΈΠ· массива строк R.array.local_cat_facts ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 2000 миллисСкунд. - * Если вновь заэмичСнный Fact совпадаСт с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌ - пропускаСм элСмСнт. - */ fun generateCatFactPeriodically(): Flowable { - val success = Fact(context.resources.getStringArray(R.array.local_cat_facts)[Random.nextInt(5)]) - return Flowable.empty() + val factsArray = context.resources.getStringArray(R.array.local_cat_facts) + return Flowable.interval(2, TimeUnit.SECONDS, Schedulers.computation()) + .map { factsArray[Random.nextInt(factsArray.size)] } + .distinctUntilChanged() + .map { Fact(it) } } -} \ No newline at end of file +}