Skip to content

ДЗ Coroutines #3

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

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open

Conversation

shokanm
Copy link

@shokanm shokanm commented May 3, 2021

ДЗ Coroutines
Исполнитель Мустафа Шокан

app/build.gradle Outdated
//coroutine retrofit
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"
implementation "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:$retrofit_coroutines_adapter"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Несколько последних версий ретрофита поддерживают саспенд функции, так что этот адаптер уже не нужен

}
})

//++++++++++++++++++++++++++++
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Комментарии лучше убрать)

/*
### Реализовать решение ViewModel
*/
viewModel = CatsViewModel(diContainer.serviceFact, diContainer.serviceImage)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут неправильное использование ViewModel. Основная идея ViewModel в том что она умеет переживать пересоздание активити, достигается это за счет хранилища ViewModel. Поэтому есть определенные требования к тому как их создавать. Создавать их правильно не через конструктор, а через фактори метод ViewModelProviders.of Так ты привязываешь ViewModel к LifecycleOwner. И последний момент - чтобы создать ViewModel с не дефолтным конструктором ты должен реализовать Factory.

public class CatsViewModel extends ViewModelProvider.NewInstanceFactory {

   private String name;

   public CatsViewModel(String name) {
       super();
       this.name = name;
   }

   @NonNull
   @Override
   public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
       if (modelClass == CatsViewModel.class) {
           return (T) new CatsViewModel(name);
       }
       return null;
   }
}

) {

private var _catsView: ICatsView? = null
private val presenterScope =
PresenterScope(Job(), Dispatchers.Main, CoroutineName("CatsCoroutine"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь можно Job не указывать. Имеет смысл если ты хочешь передать уже созданную Job в дочерний контекст или если хочешь передать SupervisorJob

}
}

private suspend fun getCatFactResponse(): Fact {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эти функции лишние. Лучше их удалить.

import kotlinx.coroutines.launch

class CatsViewModel(
private val catsServiceFact: CatsService,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Опять лишний класс-зависимость

get() = _catsResponse

fun getCatFactImage(){
viewModelScope.launch(SupervisorJob() + CoroutineExceptionHandler{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У viewModelScope уже есть SupervisorJob в качестве элемента контекста

}
}

private suspend fun getCatFactResponse(): Fact {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ненужные функции

try {
val factResponse = getCatFactResponse()
val imageResponse = getCatImageResponse()
if (factResponse != null && imageResponse != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Они не могут быть null

coroutineContext, throwable -> CrashMonitor.trackWarning()
}) {
try {
val factResponse = getCatFactResponse()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У тебя не параллельные запросы. Сначала вызывается первый и корутина саспендится. После того как он заканчивается и она резьюмится начинает работать второй. Используй async чтобы распараллелить

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вопрос: изначально я сделал без async чтобы они выполнялись полседовательно
чтобы два результата использовать при создании объекта
FactImage(factResponse, imageResponse)
теперь при использовании async как это будет работать?
допустим получаем результат factResponse, imageResponse - неодновременно
FactImage(factResponse, imageResponse) будет создан из того что пришло первым,
а второй параметр "уйдет" пустым
или
родительская корутину (которая запускает launch)
"дождется" всех и только потом создаст FactImage(factResponse, imageResponse) ?

@antonkazakov
Copy link
Collaborator

Привет. Посмотрел правки. Работу принимаю, но пожалуйста поправь первое замечание про диспатчеры)

val imageResponse = getCatImageResponse()
if (factResponse != null
&& imageResponse != null ) {
withContext(Dispatchers.IO) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не совсем понял зачем тебе тогда launch с Dispatchers.Main если ты все тело выполняешь на Dispatchers.IO


/**
* antonkazakov: ... Используй async чтобы распараллелить
* Вопрос: изначально я сделал без async чтобы они выполнялись полседовательно
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ты можешь сам это проверить на простейшем примере. Такие вещи лучше проверять самому чтобы не забывать и понимать.

Пустого параметра не будет. У тебя корутина будет сасаспендена пока не выполнится await

@shokanm
Copy link
Author

shokanm commented Jun 1, 2021

вернул catsServiceImage: CatsService в аргументы CatsViewModel так как он нужен для вызова другого url для подгрузки фото

PavelScherbakov added a commit to PavelScherbakov/Coroutines-Homework that referenced this pull request Jul 15, 2022
firkatdavletov added a commit to firkatdavletov/Coroutines-Homework that referenced this pull request Apr 17, 2024
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
AkashevPavel added a commit to AkashevPavel/Coroutines-Homework that referenced this pull request Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants