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/CatsViewModel.kt b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt index d62eaf97..538fade5 100644 --- a/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt +++ b/app/src/main/java/otus/homework/reactivecats/CatsViewModel.kt @@ -1,44 +1,89 @@ 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() {} + 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) { + compositeDisposable.dispose() + } + } } class CatsViewModelFactory( 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() } diff --git a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt index 4481062e..4d8ecfa8 100644 --- a/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt +++ b/app/src/main/java/otus/homework/reactivecats/LocalCatFactsGenerator.kt @@ -2,20 +2,26 @@ 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( 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 * обернутую в подходящий стрим(Flowable/Single/Observable и т.п) */ fun generateCatFact(): Single { - return Single.never() + return Single.just(_generateCatFact()) } /** @@ -24,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 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