From 8c748df782a1f2ee2389712b1cc742dd28b3b0bb Mon Sep 17 00:00:00 2001 From: Vera Sokolova Date: Sun, 9 Jul 2023 15:30:43 +0500 Subject: [PATCH 1/6] [1] added suspend function, presenter scope and exception logging --- app/build.gradle | 15 +++---- .../otus/homework/coroutines/CatsPresenter.kt | 39 ++++++++++++------- .../otus/homework/coroutines/CatsService.kt | 4 +- .../java/otus/homework/coroutines/CatsView.kt | 8 +++- .../otus/homework/coroutines/CrashMonitor.kt | 8 +++- .../java/otus/homework/coroutines/Fact.kt | 22 ++--------- .../otus/homework/coroutines/MainActivity.kt | 1 + .../homework/coroutines/PresenterScope.kt | 13 +++++++ build.gradle | 2 +- 9 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/otus/homework/coroutines/PresenterScope.kt diff --git a/app/build.gradle b/app/build.gradle index 679dbba4..a8829c59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,13 +4,13 @@ plugins { } android { - compileSdkVersion 30 + compileSdkVersion 34 buildToolsVersion "30.0.3" defaultConfig { applicationId "otus.homework.coroutines" minSdkVersion 23 - targetSdkVersion 30 + targetSdkVersion 34 versionCode 1 versionName "1.0" @@ -34,12 +34,13 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.core:core-ktx:1.10.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.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.squareup.picasso:picasso:2.71828' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2' } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index e4b05120..95353256 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,28 +1,37 @@ package otus.homework.coroutines -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import java.lang.Exception +import java.net.SocketTimeoutException class CatsPresenter( private val catsService: CatsService ) { private var _catsView: ICatsView? = null + private val catsScope = PresenterScope() fun onInitComplete() { - catsService.getCatFact().enqueue(object : Callback { - - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful && response.body() != null) { - _catsView?.populate(response.body()!!) + runBlocking(Dispatchers.IO) { + catsScope.launch { + try { + val response = catsService.getCatFact() + if (response.isSuccessful && response.body() != null) { + _catsView?.populate(response.body()!!) + } + } catch (e: Exception) { + if (e is SocketTimeoutException) { + _catsView?.showToast("Не удалось получить ответ от сервером") + } else { + CrashMonitor.trackWarning(e.message.toString()) + _catsView?.showToast(e.message.toString()) + } } } - - override fun onFailure(call: Call, t: Throwable) { - CrashMonitor.trackWarning() - } - }) + } } fun attachView(catsView: ICatsView) { @@ -32,4 +41,8 @@ class CatsPresenter( fun detachView() { _catsView = null } + + fun onStop(){ + catsScope.cancel() + } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsService.kt b/app/src/main/java/otus/homework/coroutines/CatsService.kt index 479b2cfb..be937729 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsService.kt @@ -1,10 +1,10 @@ package otus.homework.coroutines -import retrofit2.Call +import retrofit2.Response import retrofit2.http.GET interface CatsService { @GET("fact") - fun getCatFact() : Call + suspend fun getCatFact() : Response } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsView.kt b/app/src/main/java/otus/homework/coroutines/CatsView.kt index 30ac2531..11ccbbe2 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -4,6 +4,7 @@ import android.content.Context import android.util.AttributeSet import android.widget.Button import android.widget.TextView +import android.widget.Toast import androidx.constraintlayout.widget.ConstraintLayout class CatsView @JvmOverloads constructor( @@ -22,11 +23,16 @@ class CatsView @JvmOverloads constructor( } override fun populate(fact: Fact) { - findViewById(R.id.fact_textView).text = fact.text + findViewById(R.id.fact_textView).text = fact.fact + } + + override fun showToast(message: String) { + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } } interface ICatsView { fun populate(fact: Fact) + fun showToast(message: String) } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt b/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt index 32e6b018..bc858777 100644 --- a/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt +++ b/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt @@ -1,10 +1,16 @@ package otus.homework.coroutines +import android.util.Log + object CrashMonitor { /** * Pretend this is Crashlytics/AppCenter */ - fun trackWarning() { + private val crashesList = ArrayList() + + fun trackWarning(message: String) { + crashesList.add(message) + Log.e("crash_mirror", message) } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/Fact.kt b/app/src/main/java/otus/homework/coroutines/Fact.kt index 15c6c7ae..643a5a33 100644 --- a/app/src/main/java/otus/homework/coroutines/Fact.kt +++ b/app/src/main/java/otus/homework/coroutines/Fact.kt @@ -3,22 +3,8 @@ package otus.homework.coroutines import com.google.gson.annotations.SerializedName data class Fact( - @field:SerializedName("createdAt") - val createdAt: String, - @field:SerializedName("deleted") - val deleted: Boolean, - @field:SerializedName("_id") - val id: String, - @field:SerializedName("text") - val text: String, - @field:SerializedName("source") - val source: String, - @field:SerializedName("used") - val used: Boolean, - @field:SerializedName("type") - val type: String, - @field:SerializedName("user") - val user: String, - @field:SerializedName("updatedAt") - val updatedAt: String + @field:SerializedName("fact") + val fact: String, + @field:SerializedName("length") + val length: Int ) \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/MainActivity.kt b/app/src/main/java/otus/homework/coroutines/MainActivity.kt index a9dafb3b..b6859d59 100644 --- a/app/src/main/java/otus/homework/coroutines/MainActivity.kt +++ b/app/src/main/java/otus/homework/coroutines/MainActivity.kt @@ -25,6 +25,7 @@ class MainActivity : AppCompatActivity() { if (isFinishing) { catsPresenter.detachView() } + catsPresenter.onStop() super.onStop() } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/PresenterScope.kt b/app/src/main/java/otus/homework/coroutines/PresenterScope.kt new file mode 100644 index 00000000..269f61d4 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/PresenterScope.kt @@ -0,0 +1,13 @@ +package otus.homework.coroutines + +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlin.coroutines.CoroutineContext + +class PresenterScope : CoroutineScope { + + override val coroutineContext: CoroutineContext + get() = Job() + Dispatchers.Main + CoroutineName("CatsCoroutine") +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8ca0a2e2..7addd4ba 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.6.20" + ext.kotlin_version = "1.8.20" repositories { mavenCentral() google() From 5ec862d1b6871407847420323e29f1a853dd2f10 Mon Sep 17 00:00:00 2001 From: Vera Sokolova Date: Mon, 10 Jul 2023 02:16:31 +0500 Subject: [PATCH 2/6] [2] image loading --- app/build.gradle | 2 ++ .../{CatsService.kt => CatsFactService.kt} | 3 +- .../homework/coroutines/CatsImageService.kt | 15 ++++++++ .../otus/homework/coroutines/CatsPresenter.kt | 19 ++++++---- .../java/otus/homework/coroutines/CatsView.kt | 11 ++++-- .../otus/homework/coroutines/DiContainer.kt | 36 +++++++++++++++++-- .../otus/homework/coroutines/MainActivity.kt | 2 +- .../homework/coroutines/model/CatModel.kt | 6 ++++ .../homework/coroutines/{ => model}/Fact.kt | 2 +- .../homework/coroutines/model/RandomCat.kt | 26 ++++++++++++++ app/src/main/res/layout/activity_main.xml | 13 +++++-- 11 files changed, 118 insertions(+), 17 deletions(-) rename app/src/main/java/otus/homework/coroutines/{CatsService.kt => CatsFactService.kt} (68%) create mode 100644 app/src/main/java/otus/homework/coroutines/CatsImageService.kt create mode 100644 app/src/main/java/otus/homework/coroutines/model/CatModel.kt rename app/src/main/java/otus/homework/coroutines/{ => model}/Fact.kt (81%) create mode 100644 app/src/main/java/otus/homework/coroutines/model/RandomCat.kt diff --git a/app/build.gradle b/app/build.gradle index a8829c59..ca4b68b1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,4 +43,6 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2' + implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.3' + testImplementation 'junit:junit:4.12' } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsService.kt b/app/src/main/java/otus/homework/coroutines/CatsFactService.kt similarity index 68% rename from app/src/main/java/otus/homework/coroutines/CatsService.kt rename to app/src/main/java/otus/homework/coroutines/CatsFactService.kt index be937729..edd51aab 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsFactService.kt @@ -1,9 +1,10 @@ package otus.homework.coroutines +import otus.homework.coroutines.model.Fact import retrofit2.Response import retrofit2.http.GET -interface CatsService { +interface CatsFactService { @GET("fact") suspend fun getCatFact() : Response diff --git a/app/src/main/java/otus/homework/coroutines/CatsImageService.kt b/app/src/main/java/otus/homework/coroutines/CatsImageService.kt new file mode 100644 index 00000000..2a5bfefa --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatsImageService.kt @@ -0,0 +1,15 @@ +package otus.homework.coroutines + +import otus.homework.coroutines.model.RandomCat +import retrofit2.Response +import retrofit2.http.GET + +interface CatsImageService { + + @GET("cat?json=true") + suspend fun getCatImage() : Response + + companion object { + const val BASE_URL = "https://cataas.com/" + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index 95353256..ce92d5da 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,14 +1,17 @@ package otus.homework.coroutines import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import otus.homework.coroutines.model.CatModel import java.lang.Exception import java.net.SocketTimeoutException class CatsPresenter( - private val catsService: CatsService + private val factService: CatsFactService, + private val imageService: CatsImageService ) { private var _catsView: ICatsView? = null @@ -18,13 +21,17 @@ class CatsPresenter( runBlocking(Dispatchers.IO) { catsScope.launch { try { - val response = catsService.getCatFact() - if (response.isSuccessful && response.body() != null) { - _catsView?.populate(response.body()!!) - } + val catFactJob = async { factService.getCatFact() } + val catImageJob = async { imageService.getCatImage() } + + val catModel = CatModel( + catFactJob.await().body()?.fact, + CatsImageService.BASE_URL + catImageJob.await().body()?.url) + + _catsView?.populate(catModel) } catch (e: Exception) { if (e is SocketTimeoutException) { - _catsView?.showToast("Не удалось получить ответ от сервером") + _catsView?.showToast("Не удалось получить ответ от сервера") } else { CrashMonitor.trackWarning(e.message.toString()) _catsView?.showToast(e.message.toString()) diff --git a/app/src/main/java/otus/homework/coroutines/CatsView.kt b/app/src/main/java/otus/homework/coroutines/CatsView.kt index 11ccbbe2..e9bab989 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -3,9 +3,12 @@ package otus.homework.coroutines import android.content.Context import android.util.AttributeSet import android.widget.Button +import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.constraintlayout.widget.ConstraintLayout +import com.squareup.picasso.Picasso +import otus.homework.coroutines.model.CatModel class CatsView @JvmOverloads constructor( context: Context, @@ -22,8 +25,10 @@ class CatsView @JvmOverloads constructor( } } - override fun populate(fact: Fact) { - findViewById(R.id.fact_textView).text = fact.fact + override fun populate(catModel: CatModel) { + findViewById(R.id.fact_textView).text = catModel.fact + val imageView = findViewById(R.id.random_cat) + Picasso.get().load(catModel.imageUrl).into(imageView) } override fun showToast(message: String) { @@ -33,6 +38,6 @@ class CatsView @JvmOverloads constructor( interface ICatsView { - fun populate(fact: Fact) + fun populate(catModel: CatModel) fun showToast(message: String) } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/DiContainer.kt b/app/src/main/java/otus/homework/coroutines/DiContainer.kt index 23ddc3b2..97ff4c87 100644 --- a/app/src/main/java/otus/homework/coroutines/DiContainer.kt +++ b/app/src/main/java/otus/homework/coroutines/DiContainer.kt @@ -1,16 +1,48 @@ package otus.homework.coroutines +import com.google.gson.GsonBuilder +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit class DiContainer { - private val retrofit by lazy { + val serviceFact: CatsFactService by lazy { retrofitCatFact.create(CatsFactService::class.java) } + val serviceImage: CatsImageService by lazy { retrofitCatImage.create(CatsImageService::class.java) } + + private val interceptor = run { + val httpLoggingInterceptor = HttpLoggingInterceptor() + httpLoggingInterceptor.apply { + httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY + } + } + + private val okHttpClient = OkHttpClient.Builder() + .addNetworkInterceptor(interceptor) // same for .addInterceptor(...) + .connectTimeout(30, TimeUnit.SECONDS) //Backend is really slow + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build() + + private val retrofitCatFact by lazy { Retrofit.Builder() + .client(okHttpClient) .baseUrl("https://catfact.ninja/") .addConverterFactory(GsonConverterFactory.create()) .build() } - val service by lazy { retrofit.create(CatsService::class.java) } + private val gson = GsonBuilder() + .setLenient() + .create() + + private val retrofitCatImage by lazy { + Retrofit.Builder() + .client(okHttpClient) + .baseUrl(CatsImageService.BASE_URL) + .addConverterFactory(GsonConverterFactory.create(gson)) + .build() + } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/MainActivity.kt b/app/src/main/java/otus/homework/coroutines/MainActivity.kt index b6859d59..6aa353cc 100644 --- a/app/src/main/java/otus/homework/coroutines/MainActivity.kt +++ b/app/src/main/java/otus/homework/coroutines/MainActivity.kt @@ -15,7 +15,7 @@ class MainActivity : AppCompatActivity() { val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView setContentView(view) - catsPresenter = CatsPresenter(diContainer.service) + catsPresenter = CatsPresenter(diContainer.serviceFact, diContainer.serviceImage) view.presenter = catsPresenter catsPresenter.attachView(view) catsPresenter.onInitComplete() diff --git a/app/src/main/java/otus/homework/coroutines/model/CatModel.kt b/app/src/main/java/otus/homework/coroutines/model/CatModel.kt new file mode 100644 index 00000000..d3a1653a --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/model/CatModel.kt @@ -0,0 +1,6 @@ +package otus.homework.coroutines.model + +data class CatModel( + val fact: String?, + val imageUrl: String? +) diff --git a/app/src/main/java/otus/homework/coroutines/Fact.kt b/app/src/main/java/otus/homework/coroutines/model/Fact.kt similarity index 81% rename from app/src/main/java/otus/homework/coroutines/Fact.kt rename to app/src/main/java/otus/homework/coroutines/model/Fact.kt index 643a5a33..8c1f3817 100644 --- a/app/src/main/java/otus/homework/coroutines/Fact.kt +++ b/app/src/main/java/otus/homework/coroutines/model/Fact.kt @@ -1,4 +1,4 @@ -package otus.homework.coroutines +package otus.homework.coroutines.model import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/otus/homework/coroutines/model/RandomCat.kt b/app/src/main/java/otus/homework/coroutines/model/RandomCat.kt new file mode 100644 index 00000000..46370dfd --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/model/RandomCat.kt @@ -0,0 +1,26 @@ +package otus.homework.coroutines.model + +import com.google.gson.annotations.SerializedName + +data class RandomCat( + @field:SerializedName("_id") + val id: String, + @field:SerializedName("tags") + val tags: List, + @field:SerializedName("owner") + val owner: String, + @field:SerializedName("createdAt") + val createdAt: String, + @field:SerializedName("updatedAt") + val updatedAt: String, + @field:SerializedName("url") + val url: String, + @field:SerializedName("size") + val size: Int, + @field:SerializedName("mimetype") + val mimetype: String, + @field:SerializedName("file") + val file: String, + @field:SerializedName("validated") + val validated: Boolean +) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9508066d..547ef103 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,12 +7,20 @@ android:layout_height="match_parent" tools:context=".MainActivity"> + + - \ No newline at end of file From 5e529fc6ab5c0450baa6a6c4fdba9c33d9ab8746 Mon Sep 17 00:00:00 2001 From: Vera Sokolova Date: Mon, 10 Jul 2023 23:37:21 +0500 Subject: [PATCH 3/6] [3] added view model --- app/build.gradle | 5 +- .../otus/homework/coroutines/CatViewModel.kt | 68 +++++++++++++++++++ .../otus/homework/coroutines/CatsPresenter.kt | 18 +++-- .../java/otus/homework/coroutines/CatsView.kt | 6 +- .../otus/homework/coroutines/MainActivity.kt | 42 +++++++++--- .../java/otus/homework/coroutines/Result.kt | 8 +++ 6 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/otus/homework/coroutines/CatViewModel.kt create mode 100644 app/src/main/java/otus/homework/coroutines/Result.kt diff --git a/app/build.gradle b/app/build.gradle index ca4b68b1..14e0455f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,5 +44,8 @@ dependencies { implementation 'com.squareup.picasso:picasso:2.71828' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2' implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.3' - testImplementation 'junit:junit:4.12' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' + implementation 'androidx.activity:activity-ktx:1.7.2' + testImplementation 'junit:junit:4.13.2' } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatViewModel.kt b/app/src/main/java/otus/homework/coroutines/CatViewModel.kt new file mode 100644 index 00000000..dbd30404 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatViewModel.kt @@ -0,0 +1,68 @@ +package otus.homework.coroutines + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.async +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import otus.homework.coroutines.model.CatModel +import java.net.SocketTimeoutException + + +class CatViewModel( + private val factService: CatsFactService, + private val imageService: CatsImageService +) : ViewModel() { + val catModel = MutableLiveData() + + class CatsViewModelFactory(private val factService: CatsFactService, + private val imageService: CatsImageService) : ViewModelProvider.Factory { + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + return CatViewModel(factService, imageService) as T + } + } + + fun onInitComplete() { + loadData() + } + + private val handler = CoroutineExceptionHandler { _, throwable -> + when (throwable) { + is SocketTimeoutException -> { + catModel.value = Result.Error(Throwable("Не удалось получить ответ от сервера")) + } + is CancellationException -> { + throw throwable + } + else -> { + CrashMonitor.trackWarning(throwable.message.toString()) + catModel.value = Result.Error(throwable) + } + } + } + + private fun loadData() { + viewModelScope.launch(handler) { + val catFactJob = async { factService.getCatFact() } + val catImageJob = async { imageService.getCatImage() } + + catModel.value = Result.Success( + CatModel( + catFactJob.await().body()?.fact, + CatsImageService.BASE_URL + catImageJob.await().body()?.url + ) + ) + + } + } + + override fun onCleared() { + super.onCleared() + viewModelScope.cancel() + } +} diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index ce92d5da..3e71ee75 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,5 +1,7 @@ package otus.homework.coroutines +import android.util.Log +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.cancel @@ -30,11 +32,17 @@ class CatsPresenter( _catsView?.populate(catModel) } catch (e: Exception) { - if (e is SocketTimeoutException) { - _catsView?.showToast("Не удалось получить ответ от сервера") - } else { - CrashMonitor.trackWarning(e.message.toString()) - _catsView?.showToast(e.message.toString()) + when (e) { + is SocketTimeoutException -> { + _catsView?.showToast("Не удалось получить ответ от сервера") + } + is CancellationException -> { + throw e + } + else -> { + CrashMonitor.trackWarning(e.message.toString()) + _catsView?.showToast(e.message.toString()) + } } } } diff --git a/app/src/main/java/otus/homework/coroutines/CatsView.kt b/app/src/main/java/otus/homework/coroutines/CatsView.kt index e9bab989..160527b5 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -16,12 +16,14 @@ class CatsView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { - var presenter :CatsPresenter? = null +// var presenter :CatsPresenter? = null + var viewModel :CatViewModel? = null override fun onFinishInflate() { super.onFinishInflate() findViewById