Страница 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ом случае нужно создать экземпляр класса

Код: Выделить всё

MyClass my = new MyClass(конструктор);
в каждой своей активити ты можешь делать новые экземпляры(не зависящие друг от друга), тут всё зависит на сколько твой асинктаск 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();
}