Урок 70. onSaveInstanceState. Сохранение данных Activity при повороте экрана

Обсуждение уроков
Andy_ua
Сообщения: 21
Зарегистрирован: 06 июл 2012, 17:23

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Andy_ua » 22 янв 2013, 19:40

было бы хорошо добавить информацию из этого урока
http://developer.alexanderklimov.ru/and ... tation.php
в частности атрибут активити android:configChanges
и метод public void onConfigurationChanged(Configuration newConfig)

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение rezak90 » 22 янв 2013, 19:55

а я в свою очередь добавлю что вписывание android:configChanges="orientation" в манифест для активити не даст возможность менять лейауты с портретного на горизонтльный
R.id.team
Политика на форуме запрещена

Аватара пользователя
brulik67
Сообщения: 16
Зарегистрирован: 17 мар 2013, 12:18

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение brulik67 » 28 авг 2013, 15:31

Доброго времени суток всем! У меня возникла такая проблема при сохранении данных.


вот код метода для сохранения данных
[syntax=java5]
protected void onSaveInstanceState(Bundle outState) {
Log.d(DEBUG_TAG, "onSaveInstanceState ---> Start");
try {
for (int i = 0; i < attrs.length(); i++) {
JSONArray attr = attrs.getJSONArray(i);
String type = attr.getString(2);
String name = attr.getString(0);
View a = attributes.get(name);
if (a != null) {
if (type.contentEquals("direccion") || type.contentEquals("ret_causes")) {
Reference r = (Reference) ((Spinner) a).getSelectedItem();
Log.d(DEBUG_TAG, "r.code = ".concat(r.getCode()));
outState.putSerializable(name, r);
}
if (type.contentEquals("date")) {
Date d = (Date) ((Spinner) a).getSelectedItem();
outState.putSerializable(name, d);
}
if (type.contentEquals("boolean")) {
boolean b = ((CheckBox) a).isChecked();
outState.putSerializable(name, b);
}
if (type.contentEquals("number") || type.contentEquals("string")) {
String s = ((TextView) a).getText().toString();
outState.putSerializable(name, s);
}
}

}
} catch (Exception e) {
e.printStackTrace();
}
outState.putSerializable("adapter", adapter);
Log.d(DEBUG_TAG, "onSaveInstanceState <---- End");
super.onSaveInstanceState(outState);
}
[/syntax]

вот код onCreate();
[syntax=java5]
...
for (int n = 0; n < attrs.length(); n++) {
JSONArray attr = attrs.getJSONArray(n);
String type = attr.getString(2);
String name = attr.getString(0);
String title = attr.getString(1);
LinearLayout root = null;
View v = null;
boolean hasTitle = true;
if (type.contentEquals("direccion") || type.contentEquals("ret_causes")) {
v = inflater.inflate(R.layout.field_direccion, null);
Cursor d;
if (type.contentEquals("direccion")) {
d = db.query("direcciones", new String[] { "code", "name" }, "parent = ?",
new String[] { client_code }, null, null, null);
} else {
d = db.query("ret_causes", new String[] { "code", "name" }, null, null, null, null, null);
}

if (d.moveToFirst()) {
sel = null;
List<Reference> data = new ArrayList<Reference>();
do {
Reference ref = new Reference(d.getString(0), d.getString(1));
if (doc_data != null) {
if (doc_data.getString(name).contentEquals(d.getString(0))) {
sel = ref;
}
}
data.add(ref);
} while (d.moveToNext());
ArrayAdapter<Reference> ca = new ArrayAdapter<Reference>(this, R.layout.doc_type_spinner, data);
Spinner sp = (Spinner) v.findViewById(R.id.field_value_d);
attributes.put(name, sp);
sp.setAdapter(ca);

Log.d(DEBUG_TAG, "preIF");

if (savedInstanceState != null) {
Log.d(DEBUG_TAG, "inIF");
Reference savedRef = (Reference) savedInstanceState.getSerializable(name);
Log.d(DEBUG_TAG, "savedRef.code = ".concat(savedRef.getCode()));
sel = savedRef;
}

if (sel != null) {
sp.setSelection(ca.getPosition(sel));
Log.d(DEBUG_TAG, "sel.code = ".concat(sel.getCode()));
}
}

d.close();
root = (LinearLayout) findViewById(R.id.document_header);
}
...
[/syntax]

Проблема в том, что данные сначала сохраняются, но потом исчезают(((
вот лог:
запуск активити:
08-28 19:22:47.197: D/debug(21834): onCreate ---> Start
08-28 19:22:48.388: D/debug(21834): preIF
08-28 19:22:48.458: D/debug(21834): onCreate <--- End
08-28 19:22:48.458: D/debug(21834): onStart
08-28 19:22:48.458: D/debug(21834): onResume

выбираем в списке значение и нажимаем на кнопку выключения экрана:
08-28 19:24:49.736: D/debug(21834): onPause
08-28 19:24:49.766: D/debug(21834): onSaveInstanceState ---> Start
08-28 19:24:49.766: D/debug(21834): r.code = 000014346
08-28 19:24:49.766: D/debug(21834): onSaveInstanceState <---- End
08-28 19:24:49.777: D/debug(21834): onStop
08-28 19:24:49.897: D/debug(21834): onDestroy
08-28 19:24:50.047: D/debug(21834): onCreate ---> Start
08-28 19:24:51.638: D/debug(21834): preIF
08-28 19:24:51.638: D/debug(21834): inIF
08-28 19:24:51.638: D/debug(21834): savedRef.code = 000014346
08-28 19:24:51.638: D/debug(21834): sel.code = 000014346
08-28 19:24:51.678: D/debug(21834): onCreate <--- End
08-28 19:24:51.678: D/debug(21834): onStart
08-28 19:24:51.678: D/debug(21834): onRestoreInstanceState
08-28 19:24:51.678: D/debug(21834): onResume
08-28 19:24:51.688: D/debug(21834): onPause

у нас вроде как всё сохраняется, но после включения экрана r.code уже другой!!!
08-28 19:26:38.893: D/debug(21834): onResume
08-28 19:26:39.073: D/debug(21834): onPause
08-28 19:26:39.073: D/debug(21834): onSaveInstanceState ---> Start
08-28 19:26:39.073: D/debug(21834): r.code = 000011438
08-28 19:26:39.073: D/debug(21834): onSaveInstanceState <---- End
08-28 19:26:39.083: D/debug(21834): onStop
08-28 19:26:39.083: D/debug(21834): onDestroy
08-28 19:26:39.313: D/debug(21834): onCreate ---> Start
08-28 19:26:40.715: D/debug(21834): preIF
08-28 19:26:40.715: D/debug(21834): inIF
08-28 19:26:40.715: D/debug(21834): savedRef.code = 000011438
08-28 19:26:40.715: D/debug(21834): sel.code = 000011438
08-28 19:26:40.745: D/debug(21834): onCreate <--- End
08-28 19:26:40.745: D/debug(21834): onStart
08-28 19:26:40.745: D/debug(21834): onRestoreInstanceState
08-28 19:26:40.755: D/debug(21834): onResume
как такое возможно ???
другие объекты которые сериализуются, восстанавливаются отлично!
пробовал восстанавливать в onRestoreInstanceState() -- эффект тот же!
этот проявляется на телефонах и планшетах, где включен режим энергосбережения.
Подскажите в чём ошибка?

ensto
Сообщения: 3
Зарегистрирован: 04 окт 2012, 23:04
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение ensto » 03 сен 2013, 21:32

В уроке метод onSaveInstanceState вызывается перед onPause, а у меня и постом выше, после метода onPause. Почему так? Это зависит от используемой версии android os?

andrews
Сообщения: 3
Зарегистрирован: 20 ноя 2013, 12:12

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение andrews » 20 ноя 2013, 17:40

Подскажите пожалуйста, у меня Активити и в ней несколько фрагментов. Насколько я понял при перевороте мы можем сохранить состояние Активити и вызвать снова тот фрагмент который был, но сам фрагмент будет полностью заново перезапускаться? Как сохранить все состояния фрагмента который был активным?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение damager82 » 20 ноя 2013, 23:26

andrews писал(а):Подскажите пожалуйста, у меня Активити и в ней несколько фрагментов. Насколько я понял при перевороте мы можем сохранить состояние Активити и вызвать снова тот фрагмент который был, но сам фрагмент будет полностью заново перезапускаться? Как сохранить все состояния фрагмента который был активным?
Посмотрите урок 104, в самом конце:
Фрагменты, так же как и Activity могут сохранять данные при своем пересоздании, например при смене экрана. Для записи используется метод onSaveInstanceState. А прочесть данные можно из Bundle в методах onCreate, onCreateView или onActivityCreated.

А чтобы при пересоздании сохранить сам объект класса Fragment, используйте метод setRetainInstance. Если передать в него true, то при пересоздании фрагмента не будут вызваны методы onDestroy и onCreate, и не будет создан новый экземпляр класса Fragment.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

andrews
Сообщения: 3
Зарегистрирован: 20 ноя 2013, 12:12

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение andrews » 22 ноя 2013, 12:03

Спасибо за ответ, все оказывается настолько просто - главное не запускать Фрагменты в Активити если savedInstanceState != null - и тогда все сохраняется как есть

Аватара пользователя
Nialon
Сообщения: 22
Зарегистрирован: 12 ноя 2013, 19:19

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Nialon » 07 дек 2013, 16:06

Можно как-то приспособить все описанное к первому запуску приложения или нет?
Интересует именно в этом ключе. Может нюансы есть? Куда копать.

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

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Fry » 07 дек 2013, 22:14

Здравствуйте.

Есть вопросы по уроку.

А зачем нам вообще морочиться с сохранением переменных при повороте экрана, если мы может просто использовать внешний класс со статическими полями для хранения переменных?

Ему будет вообще все равно - что там в Андройде обнуляется при повороте экрана.
Arbeit macht Fry

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение damager82 » 07 дек 2013, 22:40

Fry писал(а):А зачем нам вообще морочиться с сохранением переменных при повороте экрана, если мы может просто использовать внешний класс со статическими полями для хранения переменных?
Ему будет вообще все равно - что там в Андройде обнуляется при повороте экрана.
У Activity может быть несколько экземпляров.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

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

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Fry » 07 дек 2013, 23:16

А на что это влияет? Статические поля внешнего класса ведь не будут инициализироваться каждый раз по-новой, а просто будут сохранять промежуточные результаты.
Arbeit macht Fry

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение rezak90 » 07 дек 2013, 23:24

Fry писал(а):А на что это влияет? Статические поля внешнего класса ведь не будут инициализироваться каждый раз по-новой, а просто будут сохранять промежуточные результаты.
1) при многопоточности данные будут не верны;
2) данные всё время будут в памяти, а память на вес золота;
R.id.team
Политика на форуме запрещена

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

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Fry » 07 дек 2013, 23:40

1. Да, при многопоточности нужно думать что-то другое

2. А что - методы onRestoreInstanceState /onSaveInstanceState хранят данные не в памяти?
Arbeit macht Fry

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение rezak90 » 07 дек 2013, 23:51

Fry писал(а):А что - методы onRestoreInstanceState /onSaveInstanceState хранят данные не в памяти?
да, но статика то будет жить всегда, даже если мы уже на другой активити, а всё что было в бандле умрёт с активити
R.id.team
Политика на форуме запрещена

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

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Fry » 08 дек 2013, 08:31

rezak90 писал(а): да, но статика то будет жить всегда, даже если мы уже на другой активити, а всё что было в бандле умрёт с активити
А внутренние классы (внутри Активити), например для реализации AsyncTask, используются по этой же причине? Чтобы выгружать память при уничтожении Активити?
Arbeit macht Fry

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение rezak90 » 08 дек 2013, 12:03

Fry писал(а):А внутренние классы (внутри Активити), например для реализации AsyncTask, используются по этой же причине? Чтобы выгружать память при уничтожении Активити?
1) что бы иметь доступ к полям активити;
2) если этот асинктаскт используется только в этом активити то его делают внутреннем классом что бы не засорять проект;
3) часто асинктаск делают статическим классом что бы экземпляр класса был один;
R.id.team
Политика на форуме запрещена

Pavel A
Сообщения: 7
Зарегистрирован: 21 июн 2013, 15:16

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение Pavel A » 11 янв 2014, 06:20

rezak90 писал(а):
Fry писал(а):А что - методы onRestoreInstanceState /onSaveInstanceState хранят данные не в памяти?
да, но статика то будет жить всегда, даже если мы уже на другой активити, а всё что было в бандле умрёт с активити
Хотелось бы уточнить , данные в SaveInstanceState точно уничтожается вместе а активити ?
То есть , если ,например, у нас есть активити , которое вызвало другое активити , и во время работы второго , первое было уничтожено сборщиком мусора , то при возврате из второго в первое SaveInstanceState первого будет пустой и все данные в нем будут потеряны ( он запуститься , как в первый раз ) ?
Куда тогда сохранять промежуточное состояние при работе с несколькими активити в приложении

apollox
Сообщения: 23
Зарегистрирован: 07 янв 2014, 13:51

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение apollox » 17 янв 2014, 11:43

Подскажите плиз, по такому вопросу.
У меня в WebView грузится картинка из интернета.
При смене ориентации экрана она естественно грузится заново.
Как можно сохранить картинку при повороте и не загружать заново? Я тут немного запутался...

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение altwin » 17 янв 2014, 12:00

apollox писал(а):Подскажите плиз, по такому вопросу.
У меня в WebView грузится картинка из интернета.
При смене ориентации экрана она естественно грузится заново.
Как можно сохранить картинку при повороте и не загружать заново? Я тут немного запутался...
кешировать ее и брать из кеша - http://developer.android.com/training/d ... itmap.html

в api 11 и больше можно просто делать resize при повроте не перегружая страницу:
[syntax=xml]
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="adjustResize"[/syntax]
этот ответ может помочь - http://stackoverflow.com/a/2246555/2611075
Изображение

apollox
Сообщения: 23
Зарегистрирован: 07 янв 2014, 13:51

Re: Урок 70. onSaveInstanceState. Сохранение данных Activity

Сообщение apollox » 18 янв 2014, 22:25

Спасибо, android:configChanges сработало.

Ответить