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

Лучшая практика для изменения ориентации: Android

Я занимался различными практиками для обработки изменений ориентации с помощью потоков и AsyncTask. Я наткнулся на следующие решения:

  • Модель прикрепления-отсоединения: Присоединение и отключение активности к потокам и AsyncTask при сохранении их экземпляра. (Источник: 1, 2)

  • Безголовый фрагмент: Использование фрагмента без UI/headless для выполнения всех операций, связанных с потоком, и сохранения его экземпляра при изменении конфигурации. (Источник: 1, 2)

Существуют ли какие-либо другие подходы к решению этого сценария? Какова рекомендуемая практика? Я спрашиваю об этом, потому что я не мог найти универсальное решение в любом месте в документах Android.

4b9b3361

Ответ 1

Некоторые сводки

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

Мой текущий проект (только настройки)

В настоящее время я использую Отто, Loaders, Volley, Ormlite и сетевой стек на основе Apache и Service s. Я надеюсь заменить сетевой стек в какой-то момент с помощью Volley, Retrofit и, возможно, в конечном итоге Robospice.

Я лично очень люблю Отто и Воллей.


RoboSpice (Modular)

  • https://github.com/octo-online/robospice
  • http://www.youtube.com/watch?v=ONaD1mB8r-A
  • плагин/модульный подход к долгосрочным задачам
  • Это похоже на "швейцарский армейский нож" библиотек, но вам нужно знать, что делает каждый инструмент.
  • Обрабатывает вызовы REST
  • сохраняет данные через ориентацию и другие изменения.
  • может обрабатывать кэширование дисков и памяти)
  • работает с различными библиотеками HTTP и библиотеками персистентности (Gson, Jackson, Spring, OkHttp и многими из нижеперечисленных библиотек)
  • beta для поддержки Ormlite, я думаю

Дооснащение (REST) ​​

Волейбол (сетевые данные и изображения)

  • https://android.googlesource.com/platform/frameworks/volley
  • https://developers.google.com/events/io/sessions/325304728
  • Это сетевой код, который запускает магазин Google Play.
  • Быстрый, надежный
  • Управляет большинством кэширования для вас с некоторыми разумными значениями по умолчанию.
  • очень прост в использовании
  • созданный специально для очень быстрого изображения, json и т.д. loading
  • Обрабатывает все потоки для вас.

Пикассо (изображения)

  • https://github.com/square/picasso
  • Библиотека Http для загрузки изображений
  • быстро
  • очень прост в использовании

Погрузчики (Android)

  • хорошо поддерживается
  • сохраняются путем изменения ориентации и сохранения/загрузки состояния фрагмента.
  • может быть трудно получить право
  • нет кеширования

AsyncTask (Android)

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

Отто (шина событий)

  • https://github.com/square/otto
  • Шина событий, упрощающая синхронизацию между компонентами и фрагментами.
  • Очень мощная способность @Produce сохраняет последнее событие и может производить его по требованию для любых новых заинтересованных абонентов на шине.

Безглавые фрагменты (?)

  • Я лично никогда не видел, чтобы это использовалось иначе, чем Vogella tutorials, поэтому я не уверен в этом.

Сервис (Android)

  • Старый школьный путь
  • Конечный контроль, вы должны сделать все сами.
  • обычно используется с клиентом Appache или HURL и
  • пройти посылки по намерениям

Ответ 2

Почему бы вам не попробовать Loaders, в частности AsyncTaskLoader? Они доступны для предварительной сотовой связи через Support Library и идеально соответствуют жизненному циклу Activity/Fragment. Вот официальное резюме:

  • Они доступны для каждой операции и фрагмента.
  • Они обеспечивают асинхронную загрузку данных.
  • Они отслеживают источник своих данных и предоставляют новые результаты при изменении содержимого.
  • Они автоматически подключаются к последнему курсору загрузчика при воссоздании после изменения конфигурации. Таким образом, им не нужно повторно запрашивать свои данные.

Ответ 3

Фактически мы используем библиотеку RoboSpice. Он запускается в службе с предоставлением только объектов RequestListeners.

Проблема с вашим первым подходом (сохранение ссылок между AsyncTask) заключается в том, что вы, возможно, можете генерировать утечки памяти, потому что, когда ваши AsyncTasks содержат ваши ссылки на действия, они будут а не сбор мусора. Следите за этим только профилированием вашего приложения, проверяя размер кучи, который снова и снова повторял одно и то же действие. Ваша куча должна расти в нормальных параметрах (есть момент, когда ваши объекты, которые должны быть собраны в мусор, в одно и то же время связаны с новыми объектами), но когда GC запускает ваше распределение памяти, вы должны упасть до того же размера, который вы выделили на начало.

Итак, если мне нужно порекомендовать что-то, это будет следующее:

Активность управления вызовами API и потоками (с помощью RoboSpice, позволяя вращению UI) Простые экраны внутри фрагментов с использованием функции keepInstance в true. Это позволит вам передавать свои DTO непосредственно вашим фрагментам, и вам нужно управлять состоянием только на самом высоком уровне.

Ответ 4

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

(1) Инициализировать любое значение до создания таким образом.

Boolean android_hacker = false;

(2) Теперь, когда вы закончите загрузку данных в классе AsyncTask, установите для этого значения значение true

android_hacker = true;

Здесь поддерживаются все данные, использующие модель и класс адаптера Array

(3) Теперь каждая временная ориентация изменяется, а затем проверяйте это как

if( android_hacker = true ){

// Use your saved instance ..

}else{

// Download data as it is yet not downloaded ..

}

Надеюсь, что это поможет.

Ответ 5

Есть много способов, которыми вы можете попробовать рядом с AsyncTask. И если вы попытаетесь найти наилучшую практику, AsyncTask - не лучший вариант. Этот ответ объясняет, почему вы не должны использовать AsyncTask. И они рекомендуют вам использовать лучший способ, который может работать с долговременной задачей, RoboSpice.
Я уже использовал эту библиотеку, и я думаю, что стоит попробовать: уважать действия lifecycles (изменение ориентации), не утечки памяти, поддерживает многопоточность, результаты кэшей... Он может подключать и отключать длительную задачу запроса, используя кеш (но он не может работать хорошо для запроса без кэша).

Но я рекомендую хороший путь от Google: IntentService и BroadcastReceiver. Вы будете регистрировать и незарегистрировать трансляцию во время изменения ориентации, чтобы получить результат данных. Вся фоновая задача будет работать в IntentService и уведомлять все, что вы хотите для деятельности BroadcastReceiver. Есть много примеров, которые вы можете попробовать. Что-то вроде этого: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

Обновление

Hi R4j, точка - мое приложение - тихий комплекс. И я должен сделать количество параллельных сетевых вызовов. Ваш подход с IntentService хорошо, но не подходит для сложных сценариев

Я не думаю, что это проблема. Вы можете делать что-либо с IntentService, даже сложные задачи. Если вам нужны параллельные задачи, вы можете рассмотреть Службу с многопотоковой обработкой в ​​ней и общаться с активностью с помощью Intent. Передача намерений между Сервисом и активностью является безопасной и гибкой, то есть способом Android.
И если вы хотите кэшировать (по загрузке файла, потоку, по базе данных..) RoboSpice - лучший выбор для вас

Ответ 6

Вы можете попробовать следующие подходы:

1) Если ваше приложение явно не требует каких-либо изменений ориентации, просто отключите изменения ориентации в начале выполнения приложения, таким образом, вы избежите любых сбоев или связанных с ними проблем в отношении изменений ориентации.

Это можно сделать, используя следующую строку в самом внешнем расположении вашего XML файла макета:

  android:orientation="vertical"

(для установки вертикальной ориентации)

2) Вы можете установить или сохранить предыдущие значения ориентации в начале выполнения потока с помощью Asynctask, как показано ниже (только пример синтаксиса):

  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

и

  getResources().getConfiguration().orientation