Skip to content

Commit d8bc68e

Browse files
Otus-Android#1 Переход с коллбеков на саспенд функции и корутины
1. Изменен возвращаемый тип в `CatsService` и добавлен модификатор `suspend` 2. Переписана логика в презентере с `Callback` на корутины и `suspend` функции 3. Реализован свой скоуп: PresenterScope с `MainDispatcher` и CoroutineName("CatsCoroutine") в качестве элементов контекста 4. Добавлена обработка исключений через try-catch. В случае `java.net.SocketTimeoutException` показываем Toast с текстом "Не удалось получить ответ от сервером". В остальных случаях логируем исключение в `otus.homework.coroutines.CrashMonitor` и показываем Toast с `exception.message`
1 parent bc8b28c commit d8bc68e

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed
Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,50 @@
11
package otus.homework.coroutines
22

3-
import retrofit2.Call
4-
import retrofit2.Callback
5-
import retrofit2.Response
3+
import kotlinx.coroutines.CoroutineName
4+
import kotlinx.coroutines.CoroutineScope
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.Job
7+
import kotlinx.coroutines.cancel
8+
import kotlinx.coroutines.launch
9+
import kotlinx.coroutines.withContext
10+
import java.net.SocketTimeoutException
11+
import kotlin.coroutines.CoroutineContext
612

713
class CatsPresenter(
814
private val catsService: CatsService
9-
) {
10-
15+
): CoroutineScope {
16+
private val job = Job()
17+
override val coroutineContext: CoroutineContext = CoroutineName("CatsCoroutine") + job
1118
private var _catsView: ICatsView? = null
1219

13-
fun onInitComplete() {
14-
catsService.getCatFact().enqueue(object : Callback<Fact> {
1520

16-
override fun onResponse(call: Call<Fact>, response: Response<Fact>) {
17-
if (response.isSuccessful && response.body() != null) {
18-
_catsView?.populate(response.body()!!)
21+
fun onInitComplete() {
22+
launch {
23+
try {
24+
val fact = catsService.getCatFact()
25+
withContext(Dispatchers.Main) {
26+
_catsView?.populate(fact)
27+
}
28+
} catch (e: Exception) {
29+
when (e) {
30+
is SocketTimeoutException -> {
31+
_catsView?.onError(R.string.connection_error_message)
32+
}
33+
else -> {
34+
CrashMonitor.trackWarning()
35+
}
1936
}
2037
}
2138

22-
override fun onFailure(call: Call<Fact>, t: Throwable) {
23-
CrashMonitor.trackWarning()
24-
}
25-
})
39+
}
2640
}
2741

2842
fun attachView(catsView: ICatsView) {
2943
_catsView = catsView
3044
}
3145

3246
fun detachView() {
47+
job.cancel()
3348
_catsView = null
3449
}
3550
}

app/src/main/java/otus/homework/coroutines/CatsService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ import retrofit2.http.GET
66
interface CatsService {
77

88
@GET("fact")
9-
fun getCatFact() : Call<Fact>
9+
suspend fun getCatFact() : Fact
1010
}

app/src/main/java/otus/homework/coroutines/CatsView.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Context
44
import android.util.AttributeSet
55
import android.widget.Button
66
import android.widget.TextView
7+
import android.widget.Toast
78
import androidx.constraintlayout.widget.ConstraintLayout
89

910
class CatsView @JvmOverloads constructor(
@@ -24,9 +25,14 @@ class CatsView @JvmOverloads constructor(
2425
override fun populate(fact: Fact) {
2526
findViewById<TextView>(R.id.fact_textView).text = fact.fact
2627
}
28+
29+
override fun onError(textResId: Int) {
30+
Toast.makeText(context, context.getText(textResId), Toast.LENGTH_LONG).show()
31+
}
2732
}
2833

2934
interface ICatsView {
3035

3136
fun populate(fact: Fact)
37+
fun onError(textResId: Int)
3238
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<resources>
22
<string name="app_name">Cat Facts </string>
33
<string name="more_facts">More Facts</string>
4+
<string name="connection_error_message">Не удалось получить ответ от сервером</string>
45
</resources>

0 commit comments

Comments
 (0)