diff --git a/app/build.gradle b/app/build.gradle index a414e0e8..7fc2f1ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,4 +41,5 @@ dependencies { implementation 'com.google.android.material:material:1.11.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.squareup.picasso:picasso:2.71828' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0' } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatImage.kt b/app/src/main/java/otus/homework/coroutines/CatImage.kt new file mode 100644 index 00000000..9efafd13 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatImage.kt @@ -0,0 +1,17 @@ +package otus.homework.coroutines + +import com.google.gson.annotations.SerializedName + +data class CatsImage( + @field:SerializedName("id") + val id: String, + + @field:SerializedName("url") + val url: String, + + @field:SerializedName("width") + val width: Int, + + @field:SerializedName("height") + val height: Int +) \ No newline at end of file diff --git a/app/src/main/java/otus/homework/coroutines/CatsInfo.kt b/app/src/main/java/otus/homework/coroutines/CatsInfo.kt new file mode 100644 index 00000000..d7d04954 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatsInfo.kt @@ -0,0 +1,6 @@ +package otus.homework.coroutines + +data class CatsInfo( + val fact: Fact, + val img: CatsImage, +) diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index e4b05120..cefa5697 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,35 +1,83 @@ package otus.homework.coroutines -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.cancel +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlin.coroutines.cancellation.CancellationException + class CatsPresenter( private val catsService: CatsService ) { - + private val presenterScope = + CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine")) + private var job: Job? = null private var _catsView: ICatsView? = null fun onInitComplete() { - catsService.getCatFact().enqueue(object : Callback { - - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful && response.body() != null) { - _catsView?.populate(response.body()!!) + job?.cancel() + job = presenterScope.launch { + try { + coroutineScope { + val fact = async { + catsService.getCatFact() + } + val image = async { + catsService.getRandomImg(IMG_URL).getOrNull(0) + ?: throw NullPointerException() + } + val factResult = fact.await() + val imageResult = image.await() + _catsView?.populate( + catsInfo = + CatsInfo( + fact = factResult, + img = imageResult, + ) + ) } + } catch (e: Exception) { + handelError(e) } + } + } - override fun onFailure(call: Call, t: Throwable) { - CrashMonitor.trackWarning() + private fun handelError(e: Exception) { + CrashMonitor.trackWarning() + val errorMsg = when (e) { + is java.net.SocketTimeoutException -> "Не удалось получить ответ от сервером" + is CancellationException -> "" + else -> e.message + } + errorMsg?.let { errorMsg -> + if (errorMsg.isNotEmpty()) { + _catsView?.showToast(errorMsg) } - }) + } } fun attachView(catsView: ICatsView) { _catsView = catsView } + fun clear() { + job?.cancel() + } + fun detachView() { _catsView = null } + + fun onDestroy() { + presenterScope.cancel() + } + + companion object { + const val IMG_URL = "https://api.thecatapi.com/v1/images/search" + } } \ 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..ac9eafea 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsService.kt @@ -1,10 +1,13 @@ package otus.homework.coroutines -import retrofit2.Call import retrofit2.http.GET +import retrofit2.http.Url interface CatsService { @GET("fact") - fun getCatFact() : Call + suspend fun getCatFact() : Fact + + @GET + suspend fun getRandomImg(@Url url: String) : Array } \ 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 be04b2a8..f12ab388 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -3,8 +3,11 @@ 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 class CatsView @JvmOverloads constructor( context: Context, @@ -12,21 +15,32 @@ class CatsView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { - var presenter :CatsPresenter? = null + var presenter: CatsPresenter? = null + private lateinit var imageView: ImageView override fun onFinishInflate() { super.onFinishInflate() findViewById