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

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

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

Вариант 1 – активность загружает данные и фрагменты.

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

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

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

Вариант 2 – Действия, упорядочивающие фрагменты, и фрагменты отвечают за выборку данных

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • После того, как метод, который использовал коммит, как правило, onCreate Activity, завершает событие CreateView, запускает onCreateView фрагмента, а иерархия элементов Fragments View добавляется к содержимому Activity.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Для более подробной информации – фрагмент-и-активность-работа-вместе .

Я предпочитаю и всегда применяю Option-2 поверх Option-1.

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

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

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

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

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

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