Skip to content

Commit 5e529fc

Browse files
vsokolikVera Sokolova
authored and
Vera Sokolova
committed
[3] added view model
1 parent 5ec862d commit 5e529fc

File tree

6 files changed

+129
-18
lines changed

6 files changed

+129
-18
lines changed

app/build.gradle

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@ dependencies {
4444
implementation 'com.squareup.picasso:picasso:2.71828'
4545
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2'
4646
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.3'
47-
testImplementation 'junit:junit:4.12'
47+
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
48+
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
49+
implementation 'androidx.activity:activity-ktx:1.7.2'
50+
testImplementation 'junit:junit:4.13.2'
4851
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package otus.homework.coroutines
2+
3+
import androidx.lifecycle.MutableLiveData
4+
import androidx.lifecycle.ViewModel
5+
import androidx.lifecycle.ViewModelProvider
6+
import androidx.lifecycle.viewModelScope
7+
import kotlinx.coroutines.CancellationException
8+
import kotlinx.coroutines.CoroutineExceptionHandler
9+
import kotlinx.coroutines.async
10+
import kotlinx.coroutines.cancel
11+
import kotlinx.coroutines.launch
12+
import otus.homework.coroutines.model.CatModel
13+
import java.net.SocketTimeoutException
14+
15+
16+
class CatViewModel(
17+
private val factService: CatsFactService,
18+
private val imageService: CatsImageService
19+
) : ViewModel() {
20+
val catModel = MutableLiveData<Result>()
21+
22+
class CatsViewModelFactory(private val factService: CatsFactService,
23+
private val imageService: CatsImageService) : ViewModelProvider.Factory {
24+
@Suppress("UNCHECKED_CAST")
25+
override fun <T : ViewModel> create(modelClass: Class<T>): T {
26+
return CatViewModel(factService, imageService) as T
27+
}
28+
}
29+
30+
fun onInitComplete() {
31+
loadData()
32+
}
33+
34+
private val handler = CoroutineExceptionHandler { _, throwable ->
35+
when (throwable) {
36+
is SocketTimeoutException -> {
37+
catModel.value = Result.Error(Throwable("Не удалось получить ответ от сервера"))
38+
}
39+
is CancellationException -> {
40+
throw throwable
41+
}
42+
else -> {
43+
CrashMonitor.trackWarning(throwable.message.toString())
44+
catModel.value = Result.Error(throwable)
45+
}
46+
}
47+
}
48+
49+
private fun loadData() {
50+
viewModelScope.launch(handler) {
51+
val catFactJob = async { factService.getCatFact() }
52+
val catImageJob = async { imageService.getCatImage() }
53+
54+
catModel.value = Result.Success(
55+
CatModel(
56+
catFactJob.await().body()?.fact,
57+
CatsImageService.BASE_URL + catImageJob.await().body()?.url
58+
)
59+
)
60+
61+
}
62+
}
63+
64+
override fun onCleared() {
65+
super.onCleared()
66+
viewModelScope.cancel()
67+
}
68+
}

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

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package otus.homework.coroutines
22

3+
import android.util.Log
4+
import kotlinx.coroutines.CancellationException
35
import kotlinx.coroutines.Dispatchers
46
import kotlinx.coroutines.async
57
import kotlinx.coroutines.cancel
@@ -30,11 +32,17 @@ class CatsPresenter(
3032

3133
_catsView?.populate(catModel)
3234
} catch (e: Exception) {
33-
if (e is SocketTimeoutException) {
34-
_catsView?.showToast("Не удалось получить ответ от сервера")
35-
} else {
36-
CrashMonitor.trackWarning(e.message.toString())
37-
_catsView?.showToast(e.message.toString())
35+
when (e) {
36+
is SocketTimeoutException -> {
37+
_catsView?.showToast("Не удалось получить ответ от сервера")
38+
}
39+
is CancellationException -> {
40+
throw e
41+
}
42+
else -> {
43+
CrashMonitor.trackWarning(e.message.toString())
44+
_catsView?.showToast(e.message.toString())
45+
}
3846
}
3947
}
4048
}

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ class CatsView @JvmOverloads constructor(
1616
defStyleAttr: Int = 0
1717
) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView {
1818

19-
var presenter :CatsPresenter? = null
19+
// var presenter :CatsPresenter? = null
20+
var viewModel :CatViewModel? = null
2021

2122
override fun onFinishInflate() {
2223
super.onFinishInflate()
2324
findViewById<Button>(R.id.button).setOnClickListener {
24-
presenter?.onInitComplete()
25+
// presenter?.onInitComplete()
26+
viewModel?.onInitComplete()
2527
}
2628
}
2729

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package otus.homework.coroutines
22

3-
import androidx.appcompat.app.AppCompatActivity
43
import android.os.Bundle
4+
import androidx.appcompat.app.AppCompatActivity
5+
import androidx.lifecycle.Observer
6+
import androidx.lifecycle.ViewModelProvider
7+
58

69
class MainActivity : AppCompatActivity() {
710

8-
lateinit var catsPresenter: CatsPresenter
11+
// lateinit var catsPresenter: CatsPresenter
12+
lateinit var catViewModel: CatViewModel
913

1014
private val diContainer = DiContainer()
1115

@@ -14,18 +18,36 @@ class MainActivity : AppCompatActivity() {
1418

1519
val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView
1620
setContentView(view)
21+
// catsPresenter = CatsPresenter(diContainer.serviceFact, diContainer.serviceImage)
22+
// view.presenter = catsPresenter
23+
// catsPresenter.attachView(view)
24+
// catsPresenter.onInitComplete()
25+
26+
catViewModel = ViewModelProvider(
27+
this,
28+
CatViewModel.CatsViewModelFactory(diContainer.serviceFact, diContainer.serviceImage)
29+
)[CatViewModel::class.java]
30+
31+
view.viewModel = catViewModel
32+
observeCats(view)
33+
catViewModel.onInitComplete()
34+
}
1735

18-
catsPresenter = CatsPresenter(diContainer.serviceFact, diContainer.serviceImage)
19-
view.presenter = catsPresenter
20-
catsPresenter.attachView(view)
21-
catsPresenter.onInitComplete()
36+
private fun observeCats(view: ICatsView) {
37+
catViewModel.catModel.observe(this, Observer {
38+
when (it) {
39+
is Result.Success -> view.populate(it.catData)
40+
is Result.Error -> view.showToast(it.throwable.message.toString())
41+
else -> {}
42+
}
43+
})
2244
}
2345

2446
override fun onStop() {
25-
if (isFinishing) {
26-
catsPresenter.detachView()
27-
}
28-
catsPresenter.onStop()
47+
// if (isFinishing) {
48+
// catsPresenter.detachView()
49+
// }
50+
// catsPresenter.onStop()
2951
super.onStop()
3052
}
3153
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package otus.homework.coroutines
2+
3+
import otus.homework.coroutines.model.CatModel
4+
5+
sealed class Result {
6+
data class Success(val catData: CatModel) : Result()
7+
data class Error(val throwable: Throwable) : Result()
8+
}

0 commit comments

Comments
 (0)