From 88b6f3536414aea159ef3ebb9b58d1aef2f285e4 Mon Sep 17 00:00:00 2001 From: Kuzmin_office Date: Fri, 6 Oct 2023 21:47:13 +0400 Subject: [PATCH 1/8] test_commit --- app/build.gradle | 7 +++++-- .../otus/homework/coroutines/CatsPresenter.kt | 21 +++++++++++++++++-- .../otus/homework/coroutines/CatsService.kt | 5 ++++- .../java/otus/homework/coroutines/CatsView.kt | 5 ++++- .../java/otus/homework/coroutines/Fact.kt | 4 +++- .../homework/coroutines/PresenterScope.kt | 15 +++++++++++++ app/src/main/res/layout/activity_main.xml | 10 +++++++++ 7 files changed, 60 insertions(+), 7 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..191b1b46 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" @@ -42,4 +42,7 @@ dependencies { implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.squareup.picasso:picasso:2.71828' + + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.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..47e2cfd7 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,5 +1,11 @@ package otus.homework.coroutines +import android.util.Log +import androidx.annotation.UiThread +import com.squareup.picasso.Picasso +import com.squareup.picasso.RequestCreator +import kotlinx.coroutines.* +import okhttp3.Dispatcher import retrofit2.Call import retrofit2.Callback import retrofit2.Response @@ -10,8 +16,10 @@ class CatsPresenter( private var _catsView: ICatsView? = null + private val presenterScope = PresenterScope() + fun onInitComplete() { - catsService.getCatFact().enqueue(object : Callback { + /*catsService.getCatFact().enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { @@ -22,7 +30,16 @@ class CatsPresenter( override fun onFailure(call: Call, t: Throwable) { CrashMonitor.trackWarning() } - }) + })*/ + + presenterScope.launch { + val fact = catsService.getCatFact() + /*val imageReq = Picasso.get() + .load("https://mustafapala.blog/wp-content/uploads/2022/10/avignolu-kizlar.jpg") + Log.d("CatPresenter", "image request: $imageReq")*/ + + _catsView?.populate(fact) + } } fun attachView(catsView: ICatsView) { diff --git a/app/src/main/java/otus/homework/coroutines/CatsService.kt b/app/src/main/java/otus/homework/coroutines/CatsService.kt index 479b2cfb..d44ce25f 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsService.kt @@ -5,6 +5,9 @@ import retrofit2.http.GET interface CatsService { + /*@GET("fact") + fun getCatFact() : Call*/ + @GET("fact") - fun getCatFact() : Call + suspend fun getCatFact(): Fact } \ 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..6a1522e5 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 androidx.constraintlayout.widget.ConstraintLayout +import com.squareup.picasso.Picasso +import com.squareup.picasso.RequestCreator class CatsView @JvmOverloads constructor( context: Context, @@ -22,7 +25,7 @@ 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 } } diff --git a/app/src/main/java/otus/homework/coroutines/Fact.kt b/app/src/main/java/otus/homework/coroutines/Fact.kt index 15c6c7ae..ff77b2e3 100644 --- a/app/src/main/java/otus/homework/coroutines/Fact.kt +++ b/app/src/main/java/otus/homework/coroutines/Fact.kt @@ -20,5 +20,7 @@ data class Fact( @field:SerializedName("user") val user: String, @field:SerializedName("updatedAt") - val updatedAt: String + val updatedAt: String, + + val fact: String ) \ 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..de642b3f --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/PresenterScope.kt @@ -0,0 +1,15 @@ +package otus.homework.coroutines + +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlin.coroutines.CoroutineContext + +class PresenterScope: CoroutineScope { + + override val coroutineContext: CoroutineContext + get() = Dispatchers.Main + CoroutineName("CatsCoroutine") + + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9508066d..68a0bed9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,6 +7,16 @@ android:layout_height="match_parent" tools:context=".MainActivity"> + + Date: Sun, 22 Oct 2023 12:41:17 +0400 Subject: [PATCH 2/8] hw_1_coroutines_part_1 --- app/build.gradle | 1 + .../otus/homework/coroutines/CatsPresenter.kt | 44 +++++++------------ .../otus/homework/coroutines/CatsService.kt | 5 --- .../java/otus/homework/coroutines/CatsView.kt | 10 +++-- .../otus/homework/coroutines/CrashMonitor.kt | 5 ++- .../otus/homework/coroutines/MainActivity.kt | 1 + .../homework/coroutines/ExampleUnitTest.kt | 2 +- 7 files changed, 30 insertions(+), 38 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 191b1b46..cf61957a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,4 +45,5 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" + testImplementation 'junit:junit:4.12' } \ 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 47e2cfd7..3e727b11 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -1,14 +1,7 @@ package otus.homework.coroutines -import android.util.Log -import androidx.annotation.UiThread -import com.squareup.picasso.Picasso -import com.squareup.picasso.RequestCreator import kotlinx.coroutines.* -import okhttp3.Dispatcher -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import java.net.SocketTimeoutException class CatsPresenter( private val catsService: CatsService @@ -16,29 +9,20 @@ class CatsPresenter( private var _catsView: ICatsView? = null - private val presenterScope = PresenterScope() + private val job = Job() + private val presenterScope = + CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine") + job) fun onInitComplete() { - /*catsService.getCatFact().enqueue(object : Callback { - - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful && response.body() != null) { - _catsView?.populate(response.body()!!) - } - } - - override fun onFailure(call: Call, t: Throwable) { - CrashMonitor.trackWarning() - } - })*/ - presenterScope.launch { - val fact = catsService.getCatFact() - /*val imageReq = Picasso.get() - .load("https://mustafapala.blog/wp-content/uploads/2022/10/avignolu-kizlar.jpg") - Log.d("CatPresenter", "image request: $imageReq")*/ - - _catsView?.populate(fact) + try { + val fact = catsService.getCatFact() + _catsView?.populate(fact) + } catch (e: SocketTimeoutException) { + _catsView?.showExceptionMessage("Не удалось получить ответ от сервера.") + } catch (e: Exception) { + CrashMonitor.trackWarning(e) + } } } @@ -49,4 +33,8 @@ class CatsPresenter( fun detachView() { _catsView = null } + + fun cancelAllJobs() { + presenterScope.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 d44ce25f..5ae3da24 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsService.kt @@ -1,13 +1,8 @@ package otus.homework.coroutines -import retrofit2.Call import retrofit2.http.GET interface CatsService { - - /*@GET("fact") - fun getCatFact() : Call*/ - @GET("fact") suspend fun getCatFact(): Fact } \ 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 6a1522e5..d12505ff 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -3,11 +3,9 @@ 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 com.squareup.picasso.RequestCreator class CatsView @JvmOverloads constructor( context: Context, @@ -27,9 +25,15 @@ class CatsView @JvmOverloads constructor( override fun populate(fact: Fact) { findViewById(R.id.fact_textView).text = fact.fact } + + override fun showExceptionMessage(text: String) { + Toast.makeText(context, text, Toast.LENGTH_SHORT).show() + } } interface ICatsView { fun populate(fact: Fact) + + fun showExceptionMessage(text: 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..6f525752 100644 --- a/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt +++ b/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt @@ -1,10 +1,13 @@ package otus.homework.coroutines +import android.util.Log + object CrashMonitor { /** * Pretend this is Crashlytics/AppCenter */ - fun trackWarning() { + fun trackWarning(e: Throwable) { + Log.d(this.toString(), e.toString()) } } \ 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..ab59d899 100644 --- a/app/src/main/java/otus/homework/coroutines/MainActivity.kt +++ b/app/src/main/java/otus/homework/coroutines/MainActivity.kt @@ -22,6 +22,7 @@ class MainActivity : AppCompatActivity() { } override fun onStop() { + catsPresenter.cancelAllJobs() if (isFinishing) { catsPresenter.detachView() } diff --git a/app/src/test/java/otus/homework/coroutines/ExampleUnitTest.kt b/app/src/test/java/otus/homework/coroutines/ExampleUnitTest.kt index 566b967d..d63aa287 100644 --- a/app/src/test/java/otus/homework/coroutines/ExampleUnitTest.kt +++ b/app/src/test/java/otus/homework/coroutines/ExampleUnitTest.kt @@ -1,8 +1,8 @@ package otus.homework.coroutines -import org.junit.Test import org.junit.Assert.* +import org.junit.Test /** * Example local unit test, which will execute on the development machine (host). From 0c067f45de93cae2029ecad4d55018733074360d Mon Sep 17 00:00:00 2001 From: Alexander Kuzmin Date: Sun, 22 Oct 2023 12:43:34 +0400 Subject: [PATCH 3/8] hw_1_coroutines_part_1_job_removed --- app/src/main/java/otus/homework/coroutines/CatsPresenter.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index 3e727b11..bda13dce 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -9,9 +9,8 @@ class CatsPresenter( private var _catsView: ICatsView? = null - private val job = Job() private val presenterScope = - CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine") + job) + CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine")) fun onInitComplete() { presenterScope.launch { From d56cef2f1234aa105da53ac537548311e5da8e86 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmin Date: Mon, 23 Oct 2023 12:11:37 +0400 Subject: [PATCH 4/8] hw_1_coroutines_part_2 --- .../java/otus/homework/coroutines/CatImage.kt | 10 ++++++ .../java/otus/homework/coroutines/CatModel.kt | 6 ++++ .../otus/homework/coroutines/CatsPresenter.kt | 36 ++++++++++++++++--- .../otus/homework/coroutines/CatsService.kt | 6 +++- .../java/otus/homework/coroutines/CatsView.kt | 12 +++++-- 5 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/otus/homework/coroutines/CatImage.kt create mode 100644 app/src/main/java/otus/homework/coroutines/CatModel.kt 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..0cf34bf6 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatImage.kt @@ -0,0 +1,10 @@ +package otus.homework.coroutines + +import com.google.gson.annotations.Expose +import com.google.gson.annotations.SerializedName + +data class CatImage( + @SerializedName("url") + @Expose + val imageUrl: String? +) diff --git a/app/src/main/java/otus/homework/coroutines/CatModel.kt b/app/src/main/java/otus/homework/coroutines/CatModel.kt new file mode 100644 index 00000000..fda7219e --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/CatModel.kt @@ -0,0 +1,6 @@ +package otus.homework.coroutines + +data class CatModel( + val fact: Fact, + val image: CatImage? +) diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt index bda13dce..79d8672c 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt @@ -13,16 +13,42 @@ class CatsPresenter( CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine")) fun onInitComplete() { - presenterScope.launch { + val deferredFact = presenterScope.async { try { - val fact = catsService.getCatFact() - _catsView?.populate(fact) + catsService.getCatFact() } catch (e: SocketTimeoutException) { - _catsView?.showExceptionMessage("Не удалось получить ответ от сервера.") + showExceptionMessage("Не удалось получить ответ от сервера.") } catch (e: Exception) { - CrashMonitor.trackWarning(e) + CrashMonitor.trackWarning(e) + showExceptionMessage(e.message ?: "") } } + + val deferredImage = presenterScope.async { + try { + catsService.getCatImage() + } catch (e: SocketTimeoutException) { + showExceptionMessage("Не удалось получить ответ от сервера.") + } catch (e: Exception) { + CrashMonitor.trackWarning(e) + showExceptionMessage(e.message ?: "") + } + } + + presenterScope.launch { + try { + val fact = deferredFact.await() as Fact + val catImage = (deferredImage.await() as List<*>).first() as CatImage + _catsView?.populate(CatModel(fact, catImage)) + } catch (e: ClassCastException) { + CrashMonitor.trackWarning(e) + showExceptionMessage(e.message ?: "") + } + } + } + + private fun showExceptionMessage(text: String) { + _catsView?.showExceptionMessage(text) } fun attachView(catsView: ICatsView) { diff --git a/app/src/main/java/otus/homework/coroutines/CatsService.kt b/app/src/main/java/otus/homework/coroutines/CatsService.kt index 5ae3da24..da8fe296 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsService.kt @@ -3,6 +3,10 @@ package otus.homework.coroutines import retrofit2.http.GET interface CatsService { - @GET("fact") + @GET("https://catfact.ninja/fact") suspend fun getCatFact(): Fact + + @GET("https://api.thecatapi.com/v1/images/search") + suspend fun getCatImage(): List + } \ 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 d12505ff..1d3b35a9 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/CatsView.kt @@ -3,9 +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, @@ -22,8 +24,12 @@ class CatsView @JvmOverloads constructor( } } - override fun populate(fact: Fact) { - findViewById(R.id.fact_textView).text = fact.fact + override fun populate(model: CatModel) { + findViewById(R.id.fact_textView).text = model.fact.fact + + Picasso.get() + .load(model.image?.imageUrl) + .into(findViewById(R.id.iv_cat)) } override fun showExceptionMessage(text: String) { @@ -33,7 +39,7 @@ class CatsView @JvmOverloads constructor( interface ICatsView { - fun populate(fact: Fact) + fun populate(model: CatModel) fun showExceptionMessage(text: String) } \ No newline at end of file From e58123e54b7e166e304fc5e7d6755729a60960b4 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmin Date: Mon, 23 Oct 2023 20:24:37 +0400 Subject: [PATCH 5/8] hw_1_coroutines_part_3_view_model --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 2 +- .../otus/homework/coroutines/CatsPresenter.kt | 65 ------------------- .../otus/homework/coroutines/CrashMonitor.kt | 20 ++++-- .../otus/homework/coroutines/MainActivity.kt | 31 --------- .../homework/coroutines/PresenterScope.kt | 15 ----- .../coroutines/{ => data}/CatsService.kt | 7 +- .../coroutines/{ => data}/DiContainer.kt | 2 +- .../coroutines/{ => domain}/CatImage.kt | 2 +- .../coroutines/{ => domain}/CatModel.kt | 2 +- .../homework/coroutines/{ => domain}/Fact.kt | 2 +- .../otus/homework/coroutines/domain/Result.kt | 6 ++ .../coroutines/presentation/CatViewModel.kt | 35 ++++++++++ .../coroutines/{ => presentation}/CatsView.kt | 14 ++-- .../coroutines/presentation/MainActivity.kt | 34 ++++++++++ app/src/main/res/layout/activity_main.xml | 2 +- 16 files changed, 106 insertions(+), 135 deletions(-) delete mode 100644 app/src/main/java/otus/homework/coroutines/CatsPresenter.kt delete mode 100644 app/src/main/java/otus/homework/coroutines/MainActivity.kt delete mode 100644 app/src/main/java/otus/homework/coroutines/PresenterScope.kt rename app/src/main/java/otus/homework/coroutines/{ => data}/CatsService.kt (56%) rename app/src/main/java/otus/homework/coroutines/{ => data}/DiContainer.kt (90%) rename app/src/main/java/otus/homework/coroutines/{ => domain}/CatImage.kt (81%) rename app/src/main/java/otus/homework/coroutines/{ => domain}/CatModel.kt (63%) rename app/src/main/java/otus/homework/coroutines/{ => domain}/Fact.kt (93%) create mode 100644 app/src/main/java/otus/homework/coroutines/domain/Result.kt create mode 100644 app/src/main/java/otus/homework/coroutines/presentation/CatViewModel.kt rename app/src/main/java/otus/homework/coroutines/{ => presentation}/CatsView.kt (76%) create mode 100644 app/src/main/java/otus/homework/coroutines/presentation/MainActivity.kt diff --git a/app/build.gradle b/app/build.gradle index cf61957a..1ad0af3d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,8 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.squareup.picasso:picasso:2.71828' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" testImplementation 'junit:junit:4.12' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fe34985b..fa531f7d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Coroutines"> - diff --git a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt b/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt deleted file mode 100644 index 79d8672c..00000000 --- a/app/src/main/java/otus/homework/coroutines/CatsPresenter.kt +++ /dev/null @@ -1,65 +0,0 @@ -package otus.homework.coroutines - -import kotlinx.coroutines.* -import java.net.SocketTimeoutException - -class CatsPresenter( - private val catsService: CatsService -) { - - private var _catsView: ICatsView? = null - - private val presenterScope = - CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine")) - - fun onInitComplete() { - val deferredFact = presenterScope.async { - try { - catsService.getCatFact() - } catch (e: SocketTimeoutException) { - showExceptionMessage("Не удалось получить ответ от сервера.") - } catch (e: Exception) { - CrashMonitor.trackWarning(e) - showExceptionMessage(e.message ?: "") - } - } - - val deferredImage = presenterScope.async { - try { - catsService.getCatImage() - } catch (e: SocketTimeoutException) { - showExceptionMessage("Не удалось получить ответ от сервера.") - } catch (e: Exception) { - CrashMonitor.trackWarning(e) - showExceptionMessage(e.message ?: "") - } - } - - presenterScope.launch { - try { - val fact = deferredFact.await() as Fact - val catImage = (deferredImage.await() as List<*>).first() as CatImage - _catsView?.populate(CatModel(fact, catImage)) - } catch (e: ClassCastException) { - CrashMonitor.trackWarning(e) - showExceptionMessage(e.message ?: "") - } - } - } - - private fun showExceptionMessage(text: String) { - _catsView?.showExceptionMessage(text) - } - - fun attachView(catsView: ICatsView) { - _catsView = catsView - } - - fun detachView() { - _catsView = null - } - - fun cancelAllJobs() { - presenterScope.cancel() - } -} \ 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 6f525752..a60894a4 100644 --- a/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt +++ b/app/src/main/java/otus/homework/coroutines/CrashMonitor.kt @@ -1,13 +1,23 @@ package otus.homework.coroutines +import android.content.Context import android.util.Log +import android.widget.Toast +import java.net.SocketTimeoutException object CrashMonitor { - /** - * Pretend this is Crashlytics/AppCenter - */ - fun trackWarning(e: Throwable) { - Log.d(this.toString(), e.toString()) + private const val SOCKET_TIME_EXCEPTION_ANSWER = "Не удалось получить ответ от сервера." + + fun trackWarning(context: Context, e: Throwable) { + when(e) { + is SocketTimeoutException -> { + Toast.makeText(context, SOCKET_TIME_EXCEPTION_ANSWER, Toast.LENGTH_SHORT).show() + } + else -> { + Log.d(this.toString(), e.toString()) + Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show() + } + } } } \ 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 deleted file mode 100644 index ab59d899..00000000 --- a/app/src/main/java/otus/homework/coroutines/MainActivity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package otus.homework.coroutines - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle - -class MainActivity : AppCompatActivity() { - - lateinit var catsPresenter: CatsPresenter - - private val diContainer = DiContainer() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - val view = layoutInflater.inflate(R.layout.activity_main, null) as CatsView - setContentView(view) - - catsPresenter = CatsPresenter(diContainer.service) - view.presenter = catsPresenter - catsPresenter.attachView(view) - catsPresenter.onInitComplete() - } - - override fun onStop() { - catsPresenter.cancelAllJobs() - if (isFinishing) { - catsPresenter.detachView() - } - 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 deleted file mode 100644 index de642b3f..00000000 --- a/app/src/main/java/otus/homework/coroutines/PresenterScope.kt +++ /dev/null @@ -1,15 +0,0 @@ -package otus.homework.coroutines - -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlin.coroutines.CoroutineContext - -class PresenterScope: CoroutineScope { - - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main + CoroutineName("CatsCoroutine") - - -} \ 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/data/CatsService.kt similarity index 56% rename from app/src/main/java/otus/homework/coroutines/CatsService.kt rename to app/src/main/java/otus/homework/coroutines/data/CatsService.kt index da8fe296..99787b22 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsService.kt +++ b/app/src/main/java/otus/homework/coroutines/data/CatsService.kt @@ -1,12 +1,13 @@ -package otus.homework.coroutines +package otus.homework.coroutines.data +import otus.homework.coroutines.domain.CatImage +import otus.homework.coroutines.domain.Fact import retrofit2.http.GET interface CatsService { - @GET("https://catfact.ninja/fact") + @GET("fact") suspend fun getCatFact(): Fact @GET("https://api.thecatapi.com/v1/images/search") suspend fun getCatImage(): List - } \ 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/data/DiContainer.kt similarity index 90% rename from app/src/main/java/otus/homework/coroutines/DiContainer.kt rename to app/src/main/java/otus/homework/coroutines/data/DiContainer.kt index 23ddc3b2..bbef489a 100644 --- a/app/src/main/java/otus/homework/coroutines/DiContainer.kt +++ b/app/src/main/java/otus/homework/coroutines/data/DiContainer.kt @@ -1,4 +1,4 @@ -package otus.homework.coroutines +package otus.homework.coroutines.data import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory diff --git a/app/src/main/java/otus/homework/coroutines/CatImage.kt b/app/src/main/java/otus/homework/coroutines/domain/CatImage.kt similarity index 81% rename from app/src/main/java/otus/homework/coroutines/CatImage.kt rename to app/src/main/java/otus/homework/coroutines/domain/CatImage.kt index 0cf34bf6..7419d6ae 100644 --- a/app/src/main/java/otus/homework/coroutines/CatImage.kt +++ b/app/src/main/java/otus/homework/coroutines/domain/CatImage.kt @@ -1,4 +1,4 @@ -package otus.homework.coroutines +package otus.homework.coroutines.domain import com.google.gson.annotations.Expose import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/otus/homework/coroutines/CatModel.kt b/app/src/main/java/otus/homework/coroutines/domain/CatModel.kt similarity index 63% rename from app/src/main/java/otus/homework/coroutines/CatModel.kt rename to app/src/main/java/otus/homework/coroutines/domain/CatModel.kt index fda7219e..13e5cddd 100644 --- a/app/src/main/java/otus/homework/coroutines/CatModel.kt +++ b/app/src/main/java/otus/homework/coroutines/domain/CatModel.kt @@ -1,4 +1,4 @@ -package otus.homework.coroutines +package otus.homework.coroutines.domain data class CatModel( val fact: Fact, diff --git a/app/src/main/java/otus/homework/coroutines/Fact.kt b/app/src/main/java/otus/homework/coroutines/domain/Fact.kt similarity index 93% rename from app/src/main/java/otus/homework/coroutines/Fact.kt rename to app/src/main/java/otus/homework/coroutines/domain/Fact.kt index ff77b2e3..8253932f 100644 --- a/app/src/main/java/otus/homework/coroutines/Fact.kt +++ b/app/src/main/java/otus/homework/coroutines/domain/Fact.kt @@ -1,4 +1,4 @@ -package otus.homework.coroutines +package otus.homework.coroutines.domain import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/otus/homework/coroutines/domain/Result.kt b/app/src/main/java/otus/homework/coroutines/domain/Result.kt new file mode 100644 index 00000000..bc085097 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/domain/Result.kt @@ -0,0 +1,6 @@ +package otus.homework.coroutines.domain + +sealed class Result { + class Error(val exception: Throwable): Result() + class Success(val catModel: CatModel): Result() +} diff --git a/app/src/main/java/otus/homework/coroutines/presentation/CatViewModel.kt b/app/src/main/java/otus/homework/coroutines/presentation/CatViewModel.kt new file mode 100644 index 00000000..5d0b4b90 --- /dev/null +++ b/app/src/main/java/otus/homework/coroutines/presentation/CatViewModel.kt @@ -0,0 +1,35 @@ +package otus.homework.coroutines.presentation + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.async +import kotlinx.coroutines.launch +import otus.homework.coroutines.data.DiContainer +import otus.homework.coroutines.domain.CatModel +import otus.homework.coroutines.domain.Result + +class CatViewModel: ViewModel(){ + + private val catsService = DiContainer().service + + private val _result = MutableLiveData() + val result: LiveData get() = _result + + private val exceptionHandler = CoroutineExceptionHandler { _, throwable -> + _result.value = Result.Error(throwable) + } + + fun onInitComplete() { + val deferredFact = viewModelScope.async { catsService.getCatFact() } + + val deferredImage = viewModelScope.async { catsService.getCatImage() } + + viewModelScope.launch(exceptionHandler) { + val catModel = CatModel(deferredFact.await(), deferredImage.await().first()) + _result.postValue(Result.Success(catModel)) + } + } +} \ 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/presentation/CatsView.kt similarity index 76% rename from app/src/main/java/otus/homework/coroutines/CatsView.kt rename to app/src/main/java/otus/homework/coroutines/presentation/CatsView.kt index 1d3b35a9..6e105d3c 100644 --- a/app/src/main/java/otus/homework/coroutines/CatsView.kt +++ b/app/src/main/java/otus/homework/coroutines/presentation/CatsView.kt @@ -5,9 +5,10 @@ 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.domain.CatModel +import otus.homework.coroutines.presentation.CatViewModel class CatsView @JvmOverloads constructor( context: Context, @@ -15,12 +16,12 @@ class CatsView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { - var presenter :CatsPresenter? = null + var catViewModel: CatViewModel? = null override fun onFinishInflate() { super.onFinishInflate() findViewById