Android-приложение сбрасывается при изменении ориентации, лучший способ справиться? - PullRequest
4 голосов
/ 05 мая 2010

Итак, я делаю простое шахматное приложение, чтобы поиграть с различными элементами андроид-программирования, и пока я многому учусь, но на этот раз я потерян.

При изменении ориентации эмулятора активность сбрасывается. Основываясь на моих исследованиях, то же самое произойдет, когда приложение будет приостановлено / прервано, т.е. смена клавиатуры, телефонный звонок, нажатие клавиши «Домой» и т. д.

Очевидно, что постоянно сбрасывать игру в шахматы нереально, поэтому мне снова нужно научиться решать эту проблему.

Мое исследование затрагивает несколько основных вещей: переопределение метода onPaused в моей Деятельности, прослушивание Ориентации, изменений клавиатуры в моем манифесте (через android: configChanges), использование Parcelables или Сериализация.

Я искал много примеров кода с использованием Pacelables, но, честно говоря, это слишком запутанно. Может быть, возвращение завтра со свежими глазами будет полезно, но сейчас, чем больше я смотрю на Parcelables, тем меньше смысла в этом.

Мое приложение использует объект Board, который имеет 64 объекта Cell (в двумерном массиве 8x8), и каждая ячейка имеет объект Piece, либо реальный кусок, либо ноль, если пространство пустое. Предполагая, что я использую Parcelable или Serialization, я предполагаю, что мне придется Parcelize или Serialize для каждого класса, платы, ячейки и части.

Прежде всего, является ли Parcelable или Serialization подходящим решением для решения этой проблемы? Если да, то для этого предпочтительнее Parcelable или Serializable? И правильно ли я, предполагая, что каждый из трех объектов должен быть Parceled / Serialized? Наконец, есть ли у кого-нибудь ссылка на простой для понимания учебник по Parcelable? Что-нибудь, что поможет мне понять и прекратить дальнейшие головные боли в будущем, когда мое приложение расширится.

Любая помощь будет оценена.

Ответы [ 5 ]

8 голосов
/ 07 мая 2010

в вашем манифесте в теге вы можете добавить android: configChanges = "direction | keyboardHidden", это предотвратит перезагрузку действия и вызовет onConfigurationChanged () вместо этого, когда ориентация изменяется или клавиатура скрыта.

Если вам нужно внести коррективы, когда произойдет любое из этих событий, вы можете переопределить onConfigurationChanged () в своей активности, если не все, что вам нужно сделать, это добавить свойство в манифест.

Что-то вроде:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.myLayout);
}

отлично работает.

3 голосов
/ 05 мая 2010

Или вставьте эту строку в свой OnCreate, чтобы он не вращался.Проблема решена.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
3 голосов
/ 05 мая 2010

Android-способ обработки событий по умолчанию - воссоздать активность. По сути, вы правильно обрабатываете один процесс, и все работает, не нужно беспокоиться об обработке этих вещей вручную.

Основы приложения имеют полный обзор жизненного цикла активности, но вкратце вы хотите сохранить состояние своей активности в методе onSaveInstanceState () и использовать Bundle, который вы получаете в onCreate (Bundle saveInstanceState) ) для восстановления состояния вашего приложения.

Если вы хотите хранить свои классы в Bundle, вам лучше всего реализовать интерфейс Parcelable . Затем для сохранения своего состояния вы делаете:

protected void onSaveInstanceState(Bundle outState)
{
  super.onSaveInstanceState(outState);
  outState.putParcelable("yourObject", mYourObject);
}

и в методе onCreate вы просто делаете:

if (savedInstanceState != null)
  mYourObject = savedInstanceState.getParcelable("yourObject");

Конечно, вы можете просто преобразовать ваши объекты в обычные представления массива, которые Bundle уже может содержать, и просто пропустить реализацию интерфейса Parcelable. В основном добавьте метод toArray () к вашему объекту и статический метод fromArray (). Что ж, поиграйте и посмотрите, что вам больше подходит.

1 голос
/ 08 мая 2010

Когда вы сохраняете состояние доски, сделайте int[64] и в каждой позиции сохраните соответствующую фигуру. Итак, 0 = пусто, 1 = белая пешка, 2 = белый конь и т. Д. ...

Когда вы загружаете состояние платы, выполняйте итерацию по массиву и создайте соответствующие кусочные объекты в соответствующих местах.

Вы можете преобразовать int [64] в строку для хранения в SharedPreferences или использовать его с Parcelable или чем-то еще. Храните только те минимальные данные, которые вам нужны.

1 голос
/ 05 мая 2010

Переопределите onRetainNonConfigurationInstance в вашем классе Activity.

В этом методе вы должны вернуть объект, просто связать состояние вашей игры в один объект состояния и вернуть его в этом методе.Убедитесь, что это только объект состояния, то есть я имею в виду, что он не должен иметь никаких дескрипторов для действий, представлений и т. Д., Содержащихся в нем, или вы получите утечку памяти.

В вашем вызове метода onCreate getLastNonConfigurationInstance дляполучить объект обратно.

Вам не нужно беспокоиться о деталях реализации (сериализации), Android позаботится об этом.

Если вы еще не убедились, что вы установиливаш режим запуска в манифесте - singleTask или singleInstance, в зависимости от того, что лучше соответствует вашим потребностям.По умолчанию, если кто-то попадает домой, а затем возвращается в ваше приложение, он запускает новую копию действия, если не обработано или не настроено для одного экземпляра, вы получите несколько запущенных копий игрового действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...