Делаем данные доступными для фрагментов

У меня есть приложение, которое извлекает данные в основном действии и отправляет событие всем фрагментам, как только оно становится доступным. Итак, для первого запуска это выглядит так:

Приложение запускается (фрагменты инициализируются в фоновом режиме) -> загрузка фида -> уведомление отправляется фрагментам -> фрагменты инициализируют пользовательский интерфейс

Пока все в порядке. НО, что, если я возобновлю работу приложения. Данные по-прежнему будут кэшироваться, поэтому я отправлю событие сразу при возобновлении работы приложения, и поэтому может случиться так, что мои фрагменты даже не готовы к приему события -> нет обновления пользовательского интерфейса фрагмента! Либо событие срабатывает и принимается во фрагменте, но фрагмент не готов к обновлению UI, потому что он еще не раздул макет -> NullpointerException Либо фрагмент получает событие, но больше не привязан к активности - > еще одно исключение. Есть способы решения отдельных проблем, но в целом это сильно усложняет архитектуру.

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

Как вы снабжаете свои фрагменты данными, если не хотите использовать пакеты?


person stoefln    schedule 06.10.2014    source источник
comment
У вас есть модель push, в которой вы пытаетесь передать данные фрагментам. Вот в чем здесь проблема. В основном состояние гонки, если фрагмент выигрывает, то все хорошо. если Activity выигрывает, появляется проблема. Пробовали ли вы комбинацию модели pull/push, когда обе стороны (активность и фрагмент) могут извлекать или отправлять данные в зависимости от доступности других. Кроме того, для извлечения из фрагмента вы можете использовать public void onActivityCreated (Bundle saveInstanceState).   -  person Gaurav Arora    schedule 06.10.2014


Ответы (1)


  • Прежде всего, Fragment должен быть независим от других частей приложения. Более того, он не должен знать родительскую активность: метод getActivity должен возвращать только Activity, который можно привести к некоторому interface.
  • Activity не должен быть "загрузчиком данных". По сути, activity — это View, который получает различные системные и пользовательские события и отображает определенное состояние. Например, когда система создает активность, она вызывает метод onCreate, где activity должен создавать/упорядочивать фрагменты и представления.
  • там должен быть какой-то manager или controller(называйте как хотите) который знает где и как брать data за просмотры. Например, если нет подключения к Интернету, он загружает данные из локальной базы данных, в противном случае он делает сетевой запрос.

Итак, грубо говоря, поток должен выглядеть так:

  1. фрагмент (или активность) имеет ссылку на файл DataManager. Фрагмент подписывается на FeedDataEvent в методе onResume. Когда фрагмент хочет (например, метод onResume) показать пользователю некоторые данные, он вызывает DataManager.loadFeed() и отображает пользователю "загрузка..."
  2. DataManager проверяет, есть ли Task, который загружает данные из сети. Если такого быстрого нет, то он его запускает.
  3. Когда данные загружаются, DataManager выдает FeedDataEvent.
  4. Если фрагмент все еще виден, он получает это событие и показывает данные. Если пользователь покинул приложение fragment, отписался (в методе onStop) от FeedEventData и не получит это событие.

Есть тонкая вещь с кешированием запросов (делать сетевой запрос каждые 24_ не очень хорошая идея), но это зависит от конкретного приложения.

PS Почти все это реализовано в RoboSpice и некоторых других библиотеках.

person eleven    schedule 06.10.2014