-
Notifications
You must be signed in to change notification settings - Fork 237
home work has been done #169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package otus.homework.coroutines | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class CatImage( | ||
@field:SerializedName("image") | ||
val image: String, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package otus.homework.coroutines | ||
|
||
import android.app.Application | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import kotlinx.coroutines.* | ||
|
||
class CatViewModel( | ||
private val catsService: CatsService, | ||
private val imageCatsService: ImageCatsService, | ||
private val application: Application, | ||
private val catsMapper: CatsMapper | ||
): ViewModel() { | ||
|
||
companion object { | ||
|
||
private const val SOCKET_TIMEOUT_EXCEPTION = "Не удалось получить ответ от сервера" | ||
private const val ERROR_MESSAGE = "Произошла ошибка" | ||
} | ||
|
||
private var _catsView: ICatsView? = null | ||
|
||
private val errorHandler = CoroutineExceptionHandler { _, exception -> | ||
CrashMonitor.trackWarning(application, exception.message ?: ERROR_MESSAGE) | ||
} | ||
|
||
fun onInitComplete() { | ||
viewModelScope.launch(errorHandler) { | ||
when(val responseResult = onInitCompleteResponse()) { | ||
is Success -> { | ||
_catsView?.populate(responseResult.data) | ||
} | ||
is Error -> { | ||
CrashMonitor.trackWarning(application, responseResult.message) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private suspend fun onInitCompleteResponse(): Result<FactAndImageModel> { | ||
return try { | ||
val response = catsService.getCatFact() | ||
val imageResponse = imageCatsService.getCatImage() | ||
if ((response.isSuccessful && response.body() != null) && (imageResponse.isSuccessful && imageResponse.body() != null)) { | ||
val factAndImage = catsMapper.toFactAndImage( | ||
fact = response.body()?.fact, | ||
image = imageResponse.body()?.image | ||
) | ||
Success(factAndImage) | ||
} else { | ||
Error(SOCKET_TIMEOUT_EXCEPTION) | ||
} | ||
} catch (e: java.net.SocketTimeoutException) { | ||
Error(SOCKET_TIMEOUT_EXCEPTION) | ||
} catch (e: Exception) { | ||
Error(e.message ?: ERROR_MESSAGE) | ||
} | ||
} | ||
|
||
fun attachView(catsView: ICatsView) { | ||
_catsView = catsView | ||
} | ||
|
||
fun detachView() { | ||
_catsView = null | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package otus.homework.coroutines | ||
|
||
class CatsMapper { | ||
|
||
fun toFactAndImage(fact: String?, image: String?): FactAndImageModel = FactAndImageModel( | ||
fact = fact.orEmpty(), | ||
image = image.orEmpty() | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,48 @@ | ||
package otus.homework.coroutines | ||
|
||
import android.content.Context | ||
import kotlinx.coroutines.* | ||
import retrofit2.Call | ||
import retrofit2.Callback | ||
import retrofit2.Response | ||
|
||
class CatsPresenter( | ||
private val catsService: CatsService | ||
private val catsService: CatsService, | ||
private val imageCatsService: ImageCatsService, | ||
private val context: Context, | ||
private val catMapper: CatsMapper | ||
) { | ||
|
||
companion object { | ||
|
||
private const val CATS_COROUTINES = "CatsCoroutine" | ||
private const val SOCKET_TIMEOUT_EXCEPTION = "Не удалось получить ответ от сервера" | ||
private const val ERROR_MESSAGE = "Произошла ошибка" | ||
} | ||
|
||
private var _catsView: ICatsView? = null | ||
|
||
fun onInitComplete() { | ||
catsService.getCatFact().enqueue(object : Callback<Fact> { | ||
private val presenterScope = CoroutineScope(Dispatchers.Main + CoroutineName(CATS_COROUTINES)) | ||
|
||
override fun onResponse(call: Call<Fact>, response: Response<Fact>) { | ||
if (response.isSuccessful && response.body() != null) { | ||
_catsView?.populate(response.body()!!) | ||
fun onInitComplete() { | ||
presenterScope.launch { | ||
try { | ||
val response = catsService.getCatFact() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. У тебя тут последовательные запросы, нужно корутины запустить |
||
val imageResponse = imageCatsService.getCatImage() | ||
if ((response.isSuccessful && response.body() != null) && (imageResponse.isSuccessful && | ||
imageResponse.body() != null)) { | ||
val factAndImage = catMapper.toFactAndImage( | ||
fact = response.body()?.fact, | ||
image = imageResponse.body()?.image | ||
) | ||
_catsView?.populate(factAndImage) | ||
} | ||
} catch (e: java.net.SocketTimeoutException) { | ||
CrashMonitor.trackWarning(context, SOCKET_TIMEOUT_EXCEPTION) | ||
} catch (e: Exception) { | ||
CrashMonitor.trackWarning(context, e.message ?: ERROR_MESSAGE) | ||
} | ||
|
||
override fun onFailure(call: Call<Fact>, t: Throwable) { | ||
CrashMonitor.trackWarning() | ||
} | ||
}) | ||
} | ||
} | ||
|
||
fun attachView(catsView: ICatsView) { | ||
|
@@ -31,5 +51,6 @@ class CatsPresenter( | |
|
||
fun detachView() { | ||
_catsView = null | ||
presenterScope.cancel() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
package otus.homework.coroutines | ||
|
||
import retrofit2.Call | ||
import retrofit2.Response | ||
import retrofit2.http.GET | ||
|
||
interface CatsService { | ||
|
||
@GET("fact") | ||
fun getCatFact() : Call<Fact> | ||
suspend fun getCatFact() : Response<Fact> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
package otus.homework.coroutines | ||
|
||
import android.content.Context | ||
import android.widget.Toast | ||
|
||
object CrashMonitor { | ||
|
||
/** | ||
* Pretend this is Crashlytics/AppCenter | ||
*/ | ||
fun trackWarning() { | ||
fun trackWarning(context: Context, message: String) { | ||
Toast.makeText(context, message, Toast.LENGTH_LONG).show() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package otus.homework.coroutines | ||
|
||
data class FactAndImageModel( | ||
val fact: String, | ||
val image: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package otus.homework.coroutines | ||
|
||
import retrofit2.Response | ||
import retrofit2.http.GET | ||
|
||
interface ImageCatsService { | ||
|
||
@GET("meow") | ||
suspend fun getCatImage(): Response<CatImage> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А зачем тебе Response, можно оставить просто CatImage, если будет неуспешный статус то тебе дефолтный КоллАдаптер выбросит исключение |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Также последовательные запросы