Подтвердить что ты не робот

Как лучше воссоздать маркеры/полилинии при повороте телефона (изменение ориентации)

Фон:

  • Разработка собственного приложения для Android, использующего Android Google Map v2, использует android.support.v4.app.FragmentActivity. Работает на Android v2.2.

Цель:

  • Сохранять маркеры/полилинии "нарисованы" на карте до изменения ориентации телефона.

Вопрос (ы):

  • Могу ли я "сохранить" маркеры/полилинии как часть пакета и просто повторить их, сохранив их в onSaveInstanceState с помощью соответствующих методов savedInstance.put.. и затем "восстановить" их в onCreate с использованием соответствующих методов savedInstanceState.get...

    В обзоре описания для Marker getID() Я смущен, когда в документации Google для Marker.getId() method указано следующее:

    Когда карта восстанавливается из Bundle, маркеры , которые были на этой карте, также восстанавливаются. Однако эти маркеры будут представлены различными объектами Marker. Идентификатор маркера можно использовать для извлечения нового экземпляра объекта Marker после такого восстановления.

    Документация Google (жирный текст выше) заставляет звучать так, как маркер просто восстанавливается автоматически, без каких-либо действий. Это не мой опыт... Может быть, я неправильно интерпретирую то, что говорится. Или, может быть, вам нужно явно сохранить карту в Bundle? Может кто-то уточнить, что это значит?

  • Предполагая, что я должен будет явно сохранить маркер и полилинии в комплекте с помощью соответствующего метода savedInstance.put..., должен ли я сохранить весь маркер или сохранить идентификатор маркера и получить информацию о маркерах с помощью идентификатора маркера повторно отобразить маркер? Я не смог найти метод put, который позволил бы мне сохранить весь маркер.

    Я заметил, что раздел MapFragment API Google Android Android v2 содержит следующее:

    Любые объекты, полученные из GoogleMap, связаны с представлением. Важно не останавливаться на объектах (например, маркерах) за пределами жизни. В противном случае это приведет к утечке памяти, поскольку представление не может быть выпущено.

    Это утверждение заставляет меня думать, что я не должен пытаться сохранить сам маркер, а вместо этого попытаюсь сохранить и сохранить идентификатор маркера, а затем повторно сгенерировать маркер на основе объекта-маркера, связанного с идентификатором маркера. Аналогично для PolyLines. Правильно ли мое предположение?

  • Кроме того, следует ли избегать использования маркера как переменной класса? Меня беспокоит, что если маркер - это переменная класса, а фрагмент карты активности помещается в задний стек, это может вызвать утечку памяти, потому что она будет эффективно "держаться за объект", как указано в вышеупомянутой документации. Это то, о чем я должен беспокоиться?

С уважением.

4b9b3361

Ответ 1

Могу ли я "сохранить" маркеры/полилинии как часть пакета и просто повторить их, сохранив их в onSaveInstanceState с помощью соответствующих методов "savedInstance.put..", а затем "восстановить" их в onCreate, используя соответствующие методы "savedInstanceState.get..".

Нет.

Документация Google (полужирный текст выше) заставляет звучать так, как маркер просто восстанавливается автоматически, без каких-либо действий. Это не мой опыт... Может быть, я неправильно интерпретирую то, что говорится. Или, может быть, вам нужно явно сохранить карту в Bundle? Может кто-то уточнить, что это значит?

Вы ничего не интерпретируете. Документация неверна.

следует сохранить идентификатор маркера и получить информацию о маркере с помощью идентификатора маркера для повторного отображения маркера

Идентификатор маркера не является чем-то постоянным при изменении конфигурации - это зависит от последовательности создания визуальных объектов (первый вызов addMarker возвращает объект с идентификатором "m1", второй "m2" ). Вы не можете использовать это значение каким-либо образом (начиная с версии API 3.1.36) и IMHO, в действительности не существует смысла. Я на самом деле опустил проблему, связанную с ID. Для Marker.getId() должна быть хотя бы функция GoogleMap.getMarkerById(String) для Marker.getId().

3) Кроме того, следует ли избегать использования маркера как переменной класса? Меня беспокоит, что если маркер - это переменная класса, а фрагмент карты активности помещается в задний стек, это может вызвать утечку памяти, потому что она будет эффективно "держаться за объект", как указано в вышеупомянутой документации. Это что-то, о чем я должен беспокоиться?

Да. Сохранение статической ссылки на Marker или любой другой визуальный объект приводит к утечке.


Не то, чтобы ответ на все ваши вопросы и проблемы приблизил его к решению, так вот мои предложения.

Я предполагаю, что у вас есть набор данных, из которых Markers и Polylines создаются и, вероятно, хранятся в БД после их получения из webservice. Теперь, если вы загрузите его из БД в AsyncTask в Activity или даже не сохраните его в DB, а только непосредственно в Activity - это плохо.

Постарайтесь сделать ваши данные максимально доступными, поэтому его нужно перезагрузить в память только после того, как процесс будет убит (или после его сброса при низком уровне памяти). Если вы это сделаете - это хорошо. Конечно, не все: если у вас есть 20000 маркеров, и каждый из них имеет изображение, отображаемое в информационном окне, оно может подождать...

Теперь, когда у вас есть все данные, необходимые для создания маркеров в памяти, просто создайте их, как и в первый раз. Дополнительный код не требуется.

Мы можем утверждать, что это хорошая или плохая идея, и я улучшу ответ, но для этого требуется больше информации о контексте:

  • сколько маркеров и полилиний
  • какие дополнительные данные у вас есть
  • где вы держите свою модель.
  • и др.

Есть, конечно, другой способ: вы можете отправить MarkerOptions в onSaveInstanceState. Это может сработать для вас, если вы сохраните его в актуальном состоянии или если ваш Markers не изменится и их не так много. Я не могу передать тысячи объектов через IPC при каждом повороте или нажав кнопку HOME.

Ответ 2

Мне кажется, что вызов setRetainInstance(true); на фрагменте, который содержит карту, сохраняет все на карте через паузы, изменения ориентации и т.д., не беспокоясь о настройке и получении. Есть ли причина, почему это не рекомендуемый подход?