Skip to content

Commit 23f6767

Browse files
committed
ДЗ - Корутины
1 parent 3cb556a commit 23f6767

File tree

8 files changed

+180
-69
lines changed

8 files changed

+180
-69
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ dependencies {
4141
implementation 'com.google.android.material:material:1.11.0'
4242
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
4343
implementation 'com.squareup.picasso:picasso:2.71828'
44+
implementation 'androidx.lifecycle:lifecycle-viewmodel-android:2.9.2'
4445
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package otus.homework.coroutines
2+
3+
data class Cat(
4+
val fact: String,
5+
val imageUrl: String
6+
)
Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
package otus.homework.coroutines
2-
3-
import kotlinx.coroutines.CoroutineName
4-
import kotlinx.coroutines.CoroutineScope
5-
import kotlinx.coroutines.Dispatchers
6-
import kotlinx.coroutines.Job
7-
import kotlinx.coroutines.async
8-
import kotlinx.coroutines.launch
9-
10-
11-
12-
class CatsPresenter(
13-
private val catsService: CatsService,
14-
private val catsImagesService: CatsImageService,
15-
private val presenterScope: CoroutineScope = CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine"))
16-
) {
17-
18-
private var _catsView: ICatsView? = null
19-
private var job: Job? = null
20-
21-
fun onInitComplete() {
22-
try {
23-
job = presenterScope.launch {
24-
val fact = async { catsService.getCatFact() }.await()
25-
val catImages:List<CatImage> = async { catsImagesService.getCatImage() }.await()
26-
_catsView?.populate(fact, catImages.first())
27-
}
28-
} catch (ex: Exception) {
29-
if (ex is java.net.SocketTimeoutException) {
30-
_catsView?.onError("Unable to get response from server")
31-
}
32-
CrashMonitor.trackWarning()
33-
}
34-
}
35-
36-
fun onStop() {
37-
job?.cancel()
38-
}
39-
40-
41-
fun attachView(catsView: ICatsView) {
42-
_catsView = catsView
43-
}
44-
45-
fun detachView() {
46-
_catsView = null
47-
}
48-
}
1+
//package otus.homework.coroutines
2+
//
3+
//import kotlinx.coroutines.CoroutineName
4+
//import kotlinx.coroutines.CoroutineScope
5+
//import kotlinx.coroutines.Dispatchers
6+
//import kotlinx.coroutines.Job
7+
//import kotlinx.coroutines.async
8+
//import kotlinx.coroutines.launch
9+
//
10+
//
11+
//
12+
//class CatsPresenter(
13+
// private val catsService: CatsService,
14+
// private val catsImagesService: CatsImageService,
15+
// private val presenterScope: CoroutineScope = CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine"))
16+
//) {
17+
//
18+
// private var _catsView: ICatsView? = null
19+
// private var job: Job? = null
20+
//
21+
// fun onInitComplete() {
22+
// try {
23+
// job = presenterScope.launch {
24+
// val fact = async { catsService.getCatFact() }.await()
25+
// val catImages:List<CatImage> = async { catsImagesService.getCatImage() }.await()
26+
// _catsView?.populate(fact, catImages.first())
27+
// }
28+
// } catch (ex: Exception) {
29+
// if (ex is java.net.SocketTimeoutException) {
30+
// _catsView?.onError("Unable to get response from server")
31+
// }
32+
// CrashMonitor.trackWarning("Error")
33+
// }
34+
// }
35+
//
36+
// fun onStop() {
37+
// job?.cancel()
38+
// }
39+
//
40+
//
41+
// fun attachView(catsView: ICatsView) {
42+
// _catsView = catsView
43+
// }
44+
//
45+
// fun detachView() {
46+
// _catsView = null
47+
// }
48+
//}

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package otus.homework.coroutines
22

33
import android.content.Context
44
import android.util.AttributeSet
5+
import android.util.Log
6+
import android.widget.Button
57
import android.widget.ImageView
68
import android.widget.TextView
79
import android.widget.Toast
@@ -15,22 +17,34 @@ class CatsView @JvmOverloads constructor(
1517
defStyleAttr: Int = 0
1618
) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView {
1719

18-
var presenter: CatsPresenter? = null
20+
// var presenter: CatsPresenter? = null
1921

20-
override fun populate(fact: Fact, image: CatImage) {
21-
findViewById<TextView>(R.id.fact_textView).text = fact.fact
22-
Picasso.get().load(image.url).into(findViewById<ImageView>(R.id.catImageView));
22+
override fun populate(cat: Cat) {
23+
findViewById<TextView>(R.id.fact_textView).text = cat.fact
24+
Picasso.get().load(cat.imageUrl).into(findViewById<ImageView>(R.id.catImageView));
2325
}
2426

2527
override fun onError(text: String) {
2628
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
2729
}
30+
31+
fun showErrorToast(errorMsg: String) {
32+
Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show()
33+
}
34+
35+
fun setOnButtonClick(onButtonClick: () -> Unit) {
36+
findViewById<Button>(R.id.button).setOnClickListener {
37+
Log.d("TAG", "Button clicked")
38+
onButtonClick()
39+
}
40+
}
41+
2842
}
2943

3044
public interface ICatsView {
3145

32-
fun populate(fact: Fact, image: CatImage)
46+
fun populate(cat: Cat)
3347

34-
fun onError(text: String)
48+
fun onError(errorMsg: String)
3549
}
3650

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package otus.homework.coroutines
2+
3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.MutableLiveData
5+
import androidx.lifecycle.ViewModel
6+
import androidx.lifecycle.ViewModelProvider
7+
import androidx.lifecycle.viewModelScope
8+
import androidx.lifecycle.viewmodel.initializer
9+
import androidx.lifecycle.viewmodel.viewModelFactory
10+
import kotlinx.coroutines.async
11+
import kotlinx.coroutines.launch
12+
import kotlinx.coroutines.CoroutineExceptionHandler
13+
14+
class CatsViewModel(
15+
private val catsService: CatsService,
16+
private val catsImageService: CatsImageService
17+
) : ViewModel() {
18+
19+
20+
private val _uiState = MutableLiveData<Result>()
21+
22+
private val exceptionHandler = CoroutineExceptionHandler { _, e ->
23+
CrashMonitor.trackWarning("${e.message}")
24+
_uiState.value = Result.Error(
25+
Throwable()
26+
)
27+
}
28+
29+
val uiState: LiveData<Result>
30+
get() = _uiState
31+
32+
fun populate () {
33+
viewModelScope.launch(exceptionHandler) {
34+
val fact = async { catsService.getCatFact() }
35+
val image = async { catsImageService.getCatImage()[0] }
36+
val cat = Cat(fact.await().fact, image.await().url)
37+
38+
_uiState.value = Result.Success(cat)
39+
}
40+
}
41+
42+
companion object {
43+
fun provideFactory(
44+
catsService: CatsService,
45+
catsImageService: CatsImageService
46+
): ViewModelProvider.Factory = viewModelFactory {
47+
initializer {
48+
CatsViewModel(catsService, catsImageService)
49+
}
50+
}
51+
}
52+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package otus.homework.coroutines
22

3+
import android.util.Log
4+
35
object CrashMonitor {
46

57
/**
68
* Pretend this is Crashlytics/AppCenter
79
*/
8-
fun trackWarning() {
10+
fun trackWarning(warningMessage: String) {
11+
Log.d("TAG", "Crash logged: $warningMessage")
912
}
1013
}

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

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,64 @@ package otus.homework.coroutines
22

33
import androidx.appcompat.app.AppCompatActivity
44
import android.os.Bundle
5+
import androidx.lifecycle.Observer
6+
import androidx.lifecycle.ViewModelProvider
7+
import otus.homework.coroutines.Result
8+
import kotlin.getValue
59

610
class MainActivity : AppCompatActivity() {
711

8-
lateinit var catsPresenter: CatsPresenter
12+
// lateinit var catsPresenter: CatsPresenter
913

1014
private val diContainer = DiContainer()
1115

16+
private val viewModel by lazy {
17+
ViewModelProvider(
18+
this,
19+
CatsViewModel.provideFactory(diContainer.catsService, diContainer.catsImageService)
20+
)[CatsViewModel::class.java]
21+
}
22+
1223
override fun onCreate(savedInstanceState: Bundle?) {
1324
super.onCreate(savedInstanceState)
1425

1526
val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView
1627
setContentView(view)
1728

18-
catsPresenter = CatsPresenter(diContainer.catsService, diContainer.catsImageService)
19-
view.presenter = catsPresenter
20-
catsPresenter.attachView(view)
21-
catsPresenter.onInitComplete()
22-
}
29+
viewModel.populate()
30+
31+
view.setOnButtonClick {
32+
viewModel.populate()
33+
34+
35+
// catsPresenter = CatsPresenter(diContainer.catsService, diContainer.catsImageService)
36+
// view.presenter = catsPresenter
37+
// catsPresenter.attachView(view)
38+
// catsPresenter.onInitComplete()
2339

24-
override fun onStop() {
25-
if (isFinishing) {
26-
catsPresenter.detachView()
2740
}
28-
super.onStop()
41+
42+
43+
val catObserver = Observer <Result> { catResult ->
44+
when(catResult) {
45+
is Result.Error -> view.showErrorToast(catResult.throwable.message.toString())
46+
is Result.Success -> view.populate(catResult.catData)
47+
48+
49+
}
50+
51+
}
52+
viewModel.uiState.observe(this, catObserver)
53+
54+
// fun onStart() {
55+
// super.onStart()
56+
// viewModel.populate()
57+
// }
58+
//
59+
// override fun onStop() {
60+
// super.onStop()
61+
// }
2962
}
30-
}
63+
}
64+
65+
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package otus.homework.coroutines
22

33

4-
sealed class Result{
5-
data class Success<out T>(val data: T) : Result()
6-
data class Error(val error: Throwable) : Result()
4+
sealed class Result {
5+
data class Success(val catData: Cat) : Result()
6+
data class Error(val throwable: Throwable) : Result()
77
}

0 commit comments

Comments
 (0)