Урок 91. AsyncTask. Поворот экрана
Урок 91. AsyncTask. Поворот экрана
В этом уроке:
- сохраняем связь с AsyncTask при повороте экрана
Click here to read this article!
- сохраняем связь с AsyncTask при повороте экрана
Click here to read this article!
Последний раз редактировалось damager82 22 май 2017, 23:40, всего редактировалось 6 раз.
-
- Сообщения: 4
- Зарегистрирован: 29 июн 2012, 03:14
Re: Урок 91. AsyncTask. Поворот экрана
Привет.
onRetainNonConfigurationInstance - это классный метод. Но не правильнее ли для продолжения АсинкТасков использовать настройки активити: android:configChanges="keyboardHidden|orientation"?
onRetainNonConfigurationInstance - это классный метод. Но не правильнее ли для продолжения АсинкТасков использовать настройки активити: android:configChanges="keyboardHidden|orientation"?
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 91. AsyncTask. Поворот экрана
Можно, только если Вы не используете разные разметки для разных ориентаций экрана.chivorotkiv писал(а):android:configChanges="keyboardHidden|orientation"?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
Re: Урок 91. AsyncTask. Поворот экрана
Спасибо за урок =)
-
- Сообщения: 4
- Зарегистрирован: 29 июн 2012, 03:14
Re: Урок 91. AsyncTask. Поворот экрана
Если я использую разные разметки для разных ориентаций экрана, то задаю новую разметку в методе onConfigurationChanged. При этом onCreate не вызывается, активити продолжает жить своей жизнью.KamiSempai писал(а):Можно, только если Вы не используете разные разметки для разных ориентаций экрана.chivorotkiv писал(а):android:configChanges="keyboardHidden|orientation"?
Re: Урок 91. AsyncTask. Поворот экрана
Если onProgressUpdate() произойдет во время поворота экрана, будет нехорошо (или вызов этого метода будет отложен до завершения поворота экрана?).
В любом случае, лучше в onProgressUpdate() добавить проверку activity != null, а в link и unlink - synchronized.
В любом случае, лучше в onProgressUpdate() добавить проверку activity != null, а в link и unlink - synchronized.
Re: Урок 91. AsyncTask. Поворот экрана
Да, проверка activity != null точно не будет лишней, иначе можно нарваться на NullPoniterException.
А synchronized для link и unlink зачем? synchronized защищает метод от одновременного запуска, а у нас тут все последовательно - старое Activity отпустило, новое приняло.
В течение дня немного дополню урок. Попробую написать решение проблемы.
А synchronized для link и unlink зачем? synchronized защищает метод от одновременного запуска, а у нас тут все последовательно - старое Activity отпустило, новое приняло.
В течение дня немного дополню урок. Попробую написать решение проблемы.
Re: Урок 91. AsyncTask. Поворот экрана
В общем, если я правильно понял, благодаря Діма и коллективному разуму эту задачу можно решить еще проще:
Достаточно объявить поля mt и tv как static, они станут объектами класса и все будет работать.
Разумеется нужно добавить проверку, чтоб задача не перезапускалась в onCreate, если она уже существует и выполняется.
Достаточно объявить поля mt и tv как static, они станут объектами класса и все будет работать.
Разумеется нужно добавить проверку, чтоб задача не перезапускалась в onCreate, если она уже существует и выполняется.
- IlyaZh
- Сообщения: 32
- Зарегистрирован: 14 июл 2012, 09:52
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Урок 91. AsyncTask. Поворот экрана
Здравствуйте. Подскажите пожалуйста. Внутри AsycnTask у меня есть следующий блок кода.
Так вот, если прописать static к Async, то среда ругается на ссылку на ресурсы и на то, что я MainActivity заменяю на activity. Иначе при повороте экрана приложение внезапно завершает свою работу, когда диалоговое окно должно закрыться методом onPostExecute().
Подскажите пожалуйста, как можно решить такую проблему?
Код: Выделить всё
@Override
protected void onPreExecute() {
pd = ProgressDialog.show(MainActivity.this, getResources().getString(R.string.app_name), "Выполняется загрузка данных", true, true);
pd.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface dialog) {
LoadDataTask.this.cancel(true);
}
});
super.onPreExecute();
}
Подскажите пожалуйста, как можно решить такую проблему?
Re: Урок 91. AsyncTask. Поворот экрана
Странно. Может не корректно заменяете?IlyaZh писал(а):Так вот, если прописать static к Async, то среда ругается на ссылку на ресурсы и на то, что я MainActivity заменяю на activity.
Так должно работать:
Код: Выделить всё
pd = ProgressDialog.show(activity, activity.getResources().getString(R.string.app_name), "Выполняется загрузка данных", true, true);
- IlyaZh
- Сообщения: 32
- Зарегистрирован: 14 июл 2012, 09:52
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Урок 91. AsyncTask. Поворот экрана
Помогло, спасибо!
Но теперь ещё проблемка.
В коде
У меня загружается функция loadPoints(), где идёт парсинг xml данных с помощью xmlpullparser. А затем спарсенные данные отправляются в другую функцию, в которой xml разбирается и на яндекс карту выводятся точки, используя данные из xml - так вот эту функцию нельзя делать статик, ибо тогда ругается на указание "this" в такой конструкции balloon.setOnBallonListener(this);
Как здесь можно поступить? Или где можно почитать подробнее про вынос async за пределы текущей активности..
Или как можно разделить парсинг и разбор?? Сохранять xml данные на sd карту не очень хочется.
Или сделать передачу параметра activiy в каждую из дочерне вызываемых функций?
Но теперь ещё проблемка.
В коде
Код: Выделить всё
@Override
protected Void doInBackground(Void... params) {
//boolean result = true;
// Загружаем данные о точках
try {
loadPoints();
} catch (Exception e) {
Log.e(DEBUG_TAG, "Unexpected failure in XML downloading and parsing", e);
}
return null;
}
Как здесь можно поступить? Или где можно почитать подробнее про вынос async за пределы текущей активности..
Или как можно разделить парсинг и разбор?? Сохранять xml данные на sd карту не очень хочется.
Или сделать передачу параметра activiy в каждую из дочерне вызываемых функций?
Re: Урок 91. AsyncTask. Поворот экрана
Нe заменяйте вложенный класс вручную.
(Перед рефакторингом сохраните проект для возможного отката)
Если класс анонимный, выполните рефакторинг Refactor/Convert Anonimous Class to Nested...
Затем
Refactor/Move Type to New File...
(Почему-то нет отдельного рефакторинга для конвертации вложенного класса в обычный)
После рефакторинга можут быть ошибки, если Эклипс не смог переделать некоторые конструкции автоматически.
В случае чего, вернитесь к старой версии.
(Перед рефакторингом сохраните проект для возможного отката)
Если класс анонимный, выполните рефакторинг Refactor/Convert Anonimous Class to Nested...
Затем
Refactor/Move Type to New File...
(Почему-то нет отдельного рефакторинга для конвертации вложенного класса в обычный)
После рефакторинга можут быть ошибки, если Эклипс не смог переделать некоторые конструкции автоматически.
В случае чего, вернитесь к старой версии.
Re: Урок 91. AsyncTask. Поворот экрана
Тоесть, если сделать отдельный клас то он не будет заново пересоздаваться и не нужно играться с ссылками?damager82 писал(а):Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity
Re: Урок 91. AsyncTask. Поворот экрана
Wa1deMar писал(а):Тоесть, если сделать отдельный клас то он не будет заново пересоздаваться и не нужно играться с ссылками?damager82 писал(а):Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity
Не совсем понял, ну да ладно, всё просто как веник
Имеем отдельный класс унаследованный от асинктаска, что6 его вызвать те6е в лю6ом случае нужно создать экземпляр класса
Код: Выделить всё
MyClass my = new MyClass(конструктор);
CEO of a company R.id.team
Re: Урок 91. AsyncTask. Поворот экрана
Есть еще одна маленькая особенность.
После того как наш textView принял конечное значение и при повороте экрана, layout присваивается первоначальное состояние. Как решение, сохранить результат в переменную и проверять в onCreate на null.
После того как наш textView принял конечное значение и при повороте экрана, layout присваивается первоначальное состояние. Как решение, сохранить результат в переменную и проверять в onCreate на null.
Re: Урок 91. AsyncTask. Поворот экрана
Как я понял android:configChanges="keyboardHidden|orientation" используется как лёгкая "заглушка", при которой всё работает, до тех пор пока кто-то не позвонит или типо того.
Но мучает вопрос, почему вы не использовали для сохранения связку onSaveInstanceState(Bundle outState)/onRestoreInstanceState(Bundle) ?
Но мучает вопрос, почему вы не использовали для сохранения связку onSaveInstanceState(Bundle outState)/onRestoreInstanceState(Bundle) ?
Re: Урок 91. AsyncTask. Поворот экрана
не пойму зачем мы добавили static или зачем класс делать не внутренним.Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity.
ведь работает внутренний класс как со static так и без...
Re: Урок 91. AsyncTask. Поворот экрана
Внутренний класс держит ссылку на внешний класс, т.е. на старое никому после поворота экрана не нужное Activity. Держит ссылку, значит держит в памяти. А зачем держать в памяти ненужный объект?gera писал(а):не пойму зачем мы добавили static или зачем класс делать не внутренним.Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity.
ведь работает внутренний класс как со static так и без...
Атрибут static избавляет внутренний класс от этой ссылки.
Re: Урок 91. AsyncTask. Поворот экрана
Делаю по примеру парсинг страницы, но при повороте все равно создается новое активити, может из-за того что передаю ссылку в execute?
Код: Выделить всё
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (parse != null)
{
parse = (Parse) getLastNonConfigurationInstance();
}
else
{
parse = new Parse();
parse.execute(URL);
}
}
Re: Урок 91. AsyncTask. Поворот экрана
Проверяй что вернет getLastNonConfigurationInstance(). Если вернет null, то создай новый объект parse = new Parse().
Если бы ты внимательно читал урок, то заметил бы этот код
Если бы ты внимательно читал урок, то заметил бы этот код
Код: Выделить всё
mt = (MyTask) getLastNonConfigurationInstance();
if (mt == null) {
mt = new MyTask();
mt.execute();
}