Урок 91. AsyncTask. Поворот экрана

Обсуждение уроков
Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 25 дек 2014, 14:27

Есть способ сделать так, чтобы AsyncTask запускался из одного активити, а данные возвращал в другой?

Можно ли сделать так, чтобы AsyncTask не привязывался к тому активити, из которого был запущен, в том числе в ситуации, когда запустившее активити уничтожается?
Arbeit macht Fry

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 25 дек 2014, 16:09

Fry писал(а):Есть способ сделать так, чтобы AsyncTask запускался из одного активити, а данные возвращал в другой?

Можно ли сделать так, чтобы AsyncTask не привязывался к тому активити, из которого был запущен, в том числе в ситуации, когда запустившее активити уничтожается?
Самый безопасный способ - это запускать задачу в сервисе, и передавать полученные данныев Activity любым удобным способом (биндинг, броадкасты, или еще что).
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 27 дек 2014, 13:55

KamiSempai, спасибо, я в курсе по поводу сервисов.

Но интересует, можно ли это сделать на ассин тасках.
Arbeit macht Fry

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Foenix » 27 дек 2014, 14:18

нельзя. Делай на фрагментах, тогда все будет запускаться и ловиться 1-й активити, а данные брать или доставлять результат можно любому фрагменту.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 29 дек 2014, 13:53

Fry писал(а):KamiSempai, спасибо, я в курсе по поводу сервисов.

Но интересует, можно ли это сделать на ассин тасках.
Так это и делается на асинк тасках, только в сервисе.
Можно сделать проще. После завершения работы асинктаска слать броадкаст при помощи LocalBroadcastManager. Тогда всякий кто подписался на это событие получит уведомление. Но этот метод не на все 100% рабочий (я бы даже сказал не на все 90% :)). При отправлении телефона в спячку, может случиться все что угодно. Но если это не критично, или задача длится не более нескольких секунд можно сделать и таким способом.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 05 янв 2015, 12:06

Так это и делается на асинк тасках, только в сервисе.
Но если уж мы делаем сервис, тогда зачем городить ассинк таск в нем? Он же и так умеет работать в отдельном потоке от GUI.
Arbeit macht Fry

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 05 янв 2015, 14:49

Fry писал(а):
Так это и делается на асинк тасках, только в сервисе.
Но если уж мы делаем сервис, тогда зачем городить ассинк таск в нем? Он же и так умеет работать в отдельном потоке от GUI.
Я вас разочарую. Почти все методы сервиса выполняются в UI потоке.

Если не верите, попробуйте подключиться к интернету в onStartCommand, получите NetworkOnMainThreadException.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 05 янв 2015, 20:48

KamiSempai писал(а):Я вас разочарую. Почти все методы сервиса выполняются в UI потоке.
Я хотел сказать, что ведь есть штатные способы сделать сервис отдельным потоком. Так зачем городить огород и запускать в самом сервис асинк таск?
Arbeit macht Fry

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 07 янв 2015, 17:17

Fry писал(а):Я хотел сказать, что ведь есть штатные способы сделать сервис отдельным потоком. Так зачем городить огород и запускать в самом сервис асинк таск?
Можно об этом по подробнее?
Я знаю, можно запустить сервис в отдельном процессе, но даже в этом случае он будет работать в UI потоке.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 08 янв 2015, 14:24

KamiSempai писал(а): Я знаю, можно запустить сервис в отдельном процессе, но даже в этом случае он будет работать в UI потоке.
Упс, а вот этого я не знал...

А почему так было сделано? Почему поток в сервисе (даже когда он отдельный) работает в UI?
Arbeit macht Fry

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 08 янв 2015, 15:09

Fry писал(а):
KamiSempai писал(а): Я знаю, можно запустить сервис в отдельном процессе, но даже в этом случае он будет работать в UI потоке.
Упс, а вот этого я не знал...

А почему так было сделано? Почему поток в сервисе (даже когда он отдельный) работает в UI?
Что бы сервис имел доступ к UI компонентам, таким как Toast или Notification. Сами подумайте, вот работает у вас сервис в одиночку, без каких либо активностей, и нужно показать Toast. Как это сделать, если нет доступа к UI?
(На самом деле предназначение сервиса не отдельный поток, а создание некоторой сущности, которая представляет из себя важную часть приложения, содержащая контекст приложения, и не дающая этому приложению завершить свою работу)

А в запуске отдельного потока не вижу проблем, несколько строк кода и готово. Для этого можно тот же AsyncTask использовать.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 08 янв 2015, 15:31

KamiSempai, спасибо огромное! Многое понял.
Arbeit macht Fry

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 15 янв 2015, 11:15

Таааак. Погодите :)

Я тут столкнулся со следующим поведением. Вот запускаю сервис с "тяжелой" задачей TimeUnit.SECONDS.sleep(10). В Активити у меня крутится ProgressBar.

Так вот. Если процесс работает в том же потоке, что и активити, ProgressBar при работе сервиса замирает (значит GUi загружен). А когда я выделяю процесс в отдельный поток, через запись в манифесте android:process=":newproc", ProgressBar при работе сервиса продолжает крутится.

Более того, делаю TimeUnit.SECONDS.sleep(100), все отрабатывает нормально - Exception не вылетает.

Почему так? Если даже работая в отдельном потоке, сервис работает в GUi-потоке, то ProgressBar должен же замереть. Разве нет?

И если "тяжелые" задачи без проблем крутятся в сервисе, созданном в отдельном потоке, то мы опять возвращаемся к вопросу о необходимости создавать AsyncTask в нем.
Arbeit macht Fry

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Mikhail_dev » 15 янв 2015, 17:01

Я знаю, можно запустить сервис в отдельном процессе, но даже в этом случае он будет работать в UI потоке.
Отдельный процесс = отдельный процесс, который имеет отдельные потоки, отчего следует что он никак не связан с UI.
Почему так? Если даже работая в отдельном потоке, сервис работает в GUi-потоке, то ProgressBar должен же замереть. Разве нет?
Вы наверное хотели сказать в отдельном процессе. В общем отдельный процесс - это отдельная копия виртуальной машины Dalvik (не совсем полная копия, но в инете зачастую говорят именно так). Запуская отдельный процесс, вы можете получить проблему того, что к примеру область памяти для статик ссылок и singleton объектов будет разная, а это значит что синглтонов и всего остального, что вы сделали как одним объектом для всего приложения, будет несколько.

Вдобавок скажу. Что будет, если ваш UI словит ошибку и упадёт? А у вас к примеру сервис с remote: фалгом. Да умрёт только процесс самого UI, а вот процесс сервиса не умрёт, ибо они независимо живут.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 15 янв 2015, 17:37

Предлагаю следующий эксперимент. Запустить сервис в отдельном процессе, из него запустить активити с прогресс баром и тут-же усыпить основной поток на несколько секунд.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Mikhail_dev » 15 янв 2015, 18:19

Я слабо понял что ты хочешь сделать. Но зачем тебе эксперименты? Поверь лучше просто мне. Я уже три года работаю с удалёнными процессами, а также тут статейки писал о проблемах процессов

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение KamiSempai » 15 янв 2015, 18:57

Mikhail_dev писал(а):Я слабо понял что ты хочешь сделать. Но зачем тебе эксперименты? Поверь лучше просто мне. Я уже три года работаю с удалёнными процессами, а также тут статейки писал о проблемах процессов
Так я не тебе предлагаю, а Fry
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Fry
Сообщения: 183
Зарегистрирован: 07 дек 2013, 22:07

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Fry » 15 янв 2015, 23:51

Отдельный процесс = отдельный процесс, который имеет отдельные потоки, отчего следует что он никак не связан с UI.
Если он никак не связан с UI, тогда как он имеет доступ к нотификейшенам, например?

И еще вопрос для моего понимания.

Насколько я знаю, процессы состоят из потоков.

Означает ли это, что два разных процесса, например активити и сервис в отдельном процессе, имеют каждый свой GUI поток?
Запуская отдельный процесс, вы можете получить проблему того, что к примеру область памяти для статик ссылок и singleton объектов будет разная, а это значит что синглтонов и всего остального, что вы сделали как одним объектом для всего приложения, будет несколько.
Я правильно понимаю, что если мы создаем отдельный поток в Service (чтобы избежать перекрытие GUI) + используем тот же процесс, что и все приложение, то мы избегаем тех проблем, о которых вы написали?

Это я просто для себя пытаюсь понять преимущества и недостатки выделения Service в отдельный процесс.

Есть еще какие-то различия (один процесс/отдельный процесс) для Service?
Есть ли отличая в жизненном цикле, относительно приложения?
Arbeit macht Fry

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение klblk » 16 янв 2015, 08:22

Мое понимание, когда нужно использовать сервис в отдельном процессе:
1) К сервису могут обращается несколько приложений
2) В сервисе выполняется долгоживущая задача, кушающая много памяти (память под процесс выделится отдельно)
Т.е. в большинстве случаев это не нужно. И самый, на мой взгляд, большой недостаток такого сервиса - это сложность реализации коммуникаций с ним.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 91. AsyncTask. Поворот экрана

Сообщение Mikhail_dev » 16 янв 2015, 10:31

Если он никак не связан с UI, тогда как он имеет доступ к нотификейшенам, например?
А собственно как нотификейшн связан с UI, кроме того, что он может открыть какую-то активность?
Означает ли это, что два разных процесса, например активити и сервис в отдельном процессе, имеют каждый свой GUI поток?
UI поток = обычный поток. Его просто назвали UI потоком. Он ничем не отличается от других. Я так понимаю там жестко прописали мол если с рутового потока запускать сетевую задачу, то писать что "NetworkOnMainThreadException". Так что да, сервисы имеют разные потоки. А GUI потоков не существует.
Я правильно понимаю, что если мы создаем отдельный поток в Service (чтобы избежать перекрытие GUI) + используем тот же процесс, что и все приложение, то мы избегаем тех проблем, о которых вы написали?
Да. Используйте IntentService, он запускает задачи в отдельном потоке (не процессе).
Это я просто для себя пытаюсь понять преимущества и недостатки выделения Service в отдельный процесс.
Это не совсем прозрачная тема. Первое - это то, что памяти выделяется больше (столько же, сколько и для нового приложения).

Ответить