Страница 1 из 6
Урок 91. AsyncTask. Поворот экрана
Добавлено: 27 июн 2012, 23:00
damager82
В этом уроке:
- сохраняем связь с AsyncTask при повороте экрана
Click here to read this article!
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 01 июл 2012, 03:30
chivorotkiv
Привет.
onRetainNonConfigurationInstance - это классный метод. Но не правильнее ли для продолжения АсинкТасков использовать настройки активити: android:configChanges="keyboardHidden|orientation"?
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 01 июл 2012, 10:27
KamiSempai
chivorotkiv писал(а):android:configChanges="keyboardHidden|orientation"?
Можно, только если Вы не используете разные разметки для разных ориентаций экрана.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 02 июл 2012, 16:04
Gorets
Спасибо за урок =)
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 05 июл 2012, 17:51
chivorotkiv
KamiSempai писал(а):chivorotkiv писал(а):android:configChanges="keyboardHidden|orientation"?
Можно, только если Вы не используете разные разметки для разных ориентаций экрана.
Если я использую разные разметки для разных ориентаций экрана, то задаю новую разметку в методе onConfigurationChanged. При этом onCreate не вызывается, активити продолжает жить своей жизнью.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 16 июл 2012, 11:51
math64
Если onProgressUpdate() произойдет во время поворота экрана, будет нехорошо (или вызов этого метода будет отложен до завершения поворота экрана?).
В любом случае, лучше в onProgressUpdate() добавить проверку activity != null, а в link и unlink - synchronized.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 17 июл 2012, 11:13
damager82
Да, проверка activity != null точно не будет лишней, иначе можно нарваться на NullPoniterException.
А synchronized для link и unlink зачем? synchronized защищает метод от одновременного запуска, а у нас тут все последовательно - старое Activity отпустило, новое приняло.
В течение дня немного дополню урок. Попробую написать решение проблемы.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 18 июл 2012, 00:18
AndreyI
В общем, если я правильно понял, благодаря Діма и коллективному разуму эту задачу можно решить еще проще:
Достаточно объявить поля mt и tv как static, они станут объектами класса и все будет работать.
Разумеется нужно добавить проверку, чтоб задача не перезапускалась в onCreate, если она уже существует и выполняется.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 19 июл 2012, 10:02
IlyaZh
Здравствуйте. Подскажите пожалуйста. Внутри AsycnTask у меня есть следующий блок кода.
Код: Выделить всё
@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();
}
Так вот, если прописать static к Async, то среда ругается на ссылку на ресурсы и на то, что я MainActivity заменяю на activity. Иначе при повороте экрана приложение внезапно завершает свою работу, когда диалоговое окно должно закрыться методом onPostExecute().
Подскажите пожалуйста, как можно решить такую проблему?
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 19 июл 2012, 13:05
damager82
IlyaZh писал(а):Так вот, если прописать static к Async, то среда ругается на ссылку на ресурсы и на то, что я MainActivity заменяю на activity.
Странно. Может не корректно заменяете?
Так должно работать:
Код: Выделить всё
pd = ProgressDialog.show(activity, activity.getResources().getString(R.string.app_name), "Выполняется загрузка данных", true, true);
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 19 июл 2012, 13:25
IlyaZh
Помогло, спасибо!
Но теперь ещё проблемка.
В коде
Код: Выделить всё
@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;
}
У меня загружается функция loadPoints(), где идёт парсинг xml данных с помощью xmlpullparser. А затем спарсенные данные отправляются в другую функцию, в которой xml разбирается и на яндекс карту выводятся точки, используя данные из xml - так вот эту функцию нельзя делать статик, ибо тогда ругается на указание "this" в такой конструкции balloon.setOnBallonListener(this);
Как здесь можно поступить? Или где можно почитать подробнее про вынос async за пределы текущей активности..
Или как можно разделить парсинг и разбор?? Сохранять xml данные на sd карту не очень хочется.
Или сделать передачу параметра activiy в каждую из дочерне вызываемых функций?
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 19 июл 2012, 17:20
math64
Нe заменяйте вложенный класс вручную.
(Перед рефакторингом сохраните проект для возможного отката)
Если класс анонимный, выполните рефакторинг Refactor/Convert Anonimous Class to Nested...
Затем
Refactor/Move Type to New File...
(Почему-то нет отдельного рефакторинга для конвертации вложенного класса в обычный)
После рефакторинга можут быть ошибки, если Эклипс не смог переделать некоторые конструкции автоматически.
В случае чего, вернитесь к старой версии.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 01 авг 2012, 11:26
Wa1deMar
damager82 писал(а):Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity
Тоесть, если сделать отдельный клас то он не будет заново пересоздаваться и не нужно играться с ссылками?
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 01 авг 2012, 13:25
Finch
Wa1deMar писал(а):damager82 писал(а):Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity
Тоесть, если сделать отдельный клас то он не будет заново пересоздаваться и не нужно играться с ссылками?
Не совсем понял, ну да ладно, всё просто как веник
Имеем отдельный класс унаследованный от асинктаска, что6 его вызвать те6е в лю6ом случае нужно создать экземпляр класса
в каждой своей активити ты можешь делать новые экземпляры(не зависящие друг от друга), тут всё зависит на сколько твой асинктаск 6удет универсален для выполнения поставленной задачи в конкретной активити =)
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 17 авг 2012, 12:29
Paul
Есть еще одна маленькая особенность.
После того как наш textView принял конечное значение и при повороте экрана, layout присваивается первоначальное состояние. Как решение, сохранить результат в переменную и проверять в onCreate на null.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 06 ноя 2012, 19:04
ilsy
Как я понял android:configChanges="keyboardHidden|orientation" используется как лёгкая "заглушка", при которой всё работает, до тех пор пока кто-то не позвонит или типо того.
Но мучает вопрос, почему вы не использовали для сохранения связку onSaveInstanceState(Bundle outState)/onRestoreInstanceState(Bundle) ?
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 15 дек 2012, 01:48
gera
Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity.
не пойму зачем мы добавили static или зачем класс делать не внутренним.
ведь работает внутренний класс как со static так и без...
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 18 дек 2012, 09:57
damager82
gera писал(а):Есть еще один способ (кроме static) избежать связки AsyncTask и Activity - просто сделайте ваш класс, наследующий AsyncTask, не внутренним, а отдельно от MainActivity.
не пойму зачем мы добавили static или зачем класс делать не внутренним.
ведь работает внутренний класс как со static так и без...
Внутренний класс держит ссылку на внешний класс, т.е. на старое никому после поворота экрана не нужное Activity. Держит ссылку, значит держит в памяти. А зачем держать в памяти ненужный объект?
Атрибут static избавляет внутренний класс от этой ссылки.
Re: Урок 91. AsyncTask. Поворот экрана
Добавлено: 22 дек 2012, 19:18
3Gern
Делаю по примеру парсинг страницы, но при повороте все равно создается новое активити, может из-за того что передаю ссылку в 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. Поворот экрана
Добавлено: 23 дек 2012, 01:02
gera
Проверяй что вернет getLastNonConfigurationInstance(). Если вернет null, то создай новый объект parse = new Parse().
Если бы ты внимательно читал урок, то заметил бы этот код
Код: Выделить всё
mt = (MyTask) getLastNonConfigurationInstance();
if (mt == null) {
mt = new MyTask();
mt.execute();
}