Действия пользователя/фрагменты Android для загрузки данных

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

  • ограничение сложности кода.
  • обработка крайних случаев (например, поворот экрана, сохранение мощности экрана, потеря подключения и т.д.).

Вариант 1 - Активность загружает данные и фрагмент, только отображает его

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

С другой стороны, активность загружает данные, используя любой метод (например, изначально последние 50 записей и при поиске, загружает результат поиска). Затем он передает его фрагменту, который отображает его. Метод загрузки данных может быть любым (от службы, от DB,... фрагментов известно только о POJO)

Это своего рода MVC-архитектура, где активностью является контроллер, а фрагменты - это вид.

Вариант 2 - операция упорядочивает фрагменты, а фрагменты отвечают за выборку данных

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

Действия - это просто способ размещения фрагментов на экране и для координации переходов между действиями приложений.

Ответ 1

В идеале ни Activity, ни Fragment с интерфейсом UI не должно содержать никакой логики "модели" - эти классы должны быть легкими и ответственными только за логику пользовательского интерфейса. Но когда вы решите создать отдельный объект модели, у вас есть дилемма, чтобы выбрать, где инициализировать и хранить этот объект и как справляться с изменениями конфигурации. И здесь идет какой-то удобный трюк:

Вы можете создать модель Fragment без пользовательского интерфейса, сделать ее сохранить экземпляр справиться с изменениями конфигурации (это AFAIK самый простой способ сохранить данные через конфигурацию без изменений) и получить его в любом месте с помощью findFragmentById(). Вы делаете все дорогостоящие операции внутри него один раз (используя фоновый поток, конечно), сохраняйте свои данные, и все готово. Для получения дополнительной информации см. Раздел Добавление фрагмента без пользовательского интерфейса.

UPD: теперь есть лучший способ справиться с изменениями конфигурации: ViewModel от Компоненты архитектуры Google. Здесь хороший пример.

Ответ 2

В теории вы можете делать все, что хотите, если оно работает. Фактически, фрагменты и действия отображают данные и обрабатывают их собственные жизненные циклы.

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

Если вы помните о том, что Фрагмент должен предоставить интерфейс и активность, должен обеспечить обработку, тогда у вас есть хорошее разделение проблем и кода, которые должны позволять повторять использование Фрагмента или Действия.

Если вы знаете о шаблоне MVC - Model View Controller - дизайн, тогда вы можете думать о фрагменте как о представлении и о деятельности как о модели.

Все становится намного интереснее, когда вы создаете приложение с несколькими фрагментами.

Некоторые ключевые моменты в качестве решающего фактора -

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

  • Фрагмент не имеет собственного пользовательского интерфейса - он отображается Действия, с которыми связан фрагмент. События сгенерированных объектами в иерархии представлений, которые принадлежат Мероприятия. Если вы попытаетесь использовать Android Studio для добавления обработчика событий, например, он добавит его в Activity, а не в Fragment.

  • Вы можете определить EventListener, с которым вы хотите обработать событие в Fragment, а затем подключите его к объекту View в Деятельность, в которой вы хотите сгенерировать событие.

  • Фрагмент - это класс, который реализует метод onCreateView для поставьте иерархию представления, которая может отображаться с помощью Activity.

  • Чтобы использовать Фрагмент в Деятельности, вы должны добавить его, используя FragmentManager и FragmentTransaction. Вы можете добавить фрагмент используя метод добавления, но ничего не происходит до тех пор, пока вы не назовете фиксацию Метод.

  • После метода, использующего фиксацию, обычно это действие onCreate, завершает событие CreateView, запускает Fragment's onCreateView и иерархия представлений фрагментов добавляются в Содержание мероприятия.

  • Вам нужно написать код для сохранения и восстановления любого дополнительного состояния. Фрагмент может иметь.

  • Если задача является общей для всех экземпляров фрагмента, то ее код должен жить во Фрагменте.

  • В частности, код для обработки событий может быть определен в пределах Фрагмент.

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

  • Присоединение обработчиков событий событий к интерфейсу фрагментов или трудно сделать правильно.

  • В сценариях принимается решение о том, каким будет ваше приложение. Это сервис, активность, виджет, даже поставщик контента или сложная система, включая некоторые другие компоненты. Проверьте свое решение против сценарии.

  • Все они должны работать после того, как фрагмент был уничтожен и воссоздан.

    (1) Initialization of the Fragment, (2) Saving and restoring the Fragment state и (3) Implementing something like an event mechanism so the Fragment can get the Activity attention

    Самая сложная часть реализует нечто вроде механизма событий.

  • В случае сложной системы распределяем функции и данных между компонентами приложения. Составить список компонентов и что они (действия или что-то еще).

  • Составьте список компонентов пользовательского интерфейса с описанием того, что они делают (не КАК все же) Это будут виджеты и действия или фрагменты или макеты позже.

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

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

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

Эффективная обработка данных с ориентацией экрана -

При изменении ориентации экрана Android перезапустит текущую активность (вызывается onDestroy(), а затем onCreate()).

Чтобы правильно обрабатывать перезагрузку, важно, чтобы ваша активность восстанавливала прежнее состояние через обычный жизненный цикл Activity, в котором Android вызывает onSaveInstanceState(), прежде чем он уничтожит вашу активность, чтобы вы могли сохранять данные о состоянии приложения. Затем вы можете восстановить состояние во время onCreate() или onRestoreInstanceState().

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

1) Сохранять объект во время изменения конфигурации

Разрешить перезагрузку вашей активности при изменении конфигурации, но переносить объект с состоянием в новый экземпляр вашей активности.

2) Обращайтесь к самому изменению конфигурации

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

Что бы я сделал, это управлять всем потоком данных (bluetooth, database storage, etc) в Управлении и использовать Фрагменты только для отображения пользовательского интерфейса или обработки пользовательского ввода.

Этот способ проще обрабатывать изменения конфигурации/вращения экрана.

Кроме того, если поток данных сильно зависит от потока пользовательского интерфейса, рассмотрите возможность использования Service с фоновым потоком. Если это "один выстрел", вы можете использовать IntentService, в противном случае вы можете реализовать Bind Service и запросить привязку из любого места, где есть Контекст.

Подробнее читайте fragment-and-activity-working-together.

Ответ 3

Я предпочитаю и всегда реализую Option-2 поверх Option-1.

Причины не выбора варианта-1:

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

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

  • Как отметил @Ved Prakash, обработка ориентации экрана становится сложной, если ориентация обрабатывается Activty.

Ответ 4

У меня есть пример: ваше приложение имеет 2 функции A и B. 2 функции независимы друг от друга. и каждая функция имеет много экрана. вы должны создать 2 действия A и B, потому что, когда используется действие A, действие B должно быть выпущено для уменьшения объема памяти приложения. И то же самое, когда B используется, A должен быть выпущен. Память Контекста A и B независима, если вы хотите отправлять данные из Activity A в B, вы должны использовать намерение или использовать глобальную переменную в Application Context. Намерение управляется ОС, а не приложением. Когда A посылает намерение B, если A уничтожается, нет проблем с отправкой намерения в B. Активность - это модуль App, он может вызывать другие приложения (фрагмент невозможен).

например: функция A имеет большой экран (например: Fragment1, Fragment2). они используют одни и те же данные и зависят друг от друга. каждый экран должен быть фрагментом. и при обработке данных вы можете получить ссылку на данные, вызвав функцию getActivity(), а затем получить ссылку на переменную контекста Activity (или Activity memory) для записи или чтения. Fragment1 и Fragment2 относятся к Activity A Context.it означает, что фрагмент 1 и фрагмент 2 могут передавать данные друг с другом через переменную контекста Activity, это легко сделать. заметил, что Intent управляется ОС, он настолько дорог, когда отправляет данные через Intent.