0

I am having an app which is retrieving data in the main activity and sending an event to all fragments as soon as it is available. So for the first start it looks like this:

App starts (fragments are initialising in the background) -> feed download -> notification sent to fragments -> fragments initialise UI

Everything's fine so far. BUT, what if I am resuming the app. The data will be still cached, so i will send the event immediately on app resume, and therefore it can happen that my fragments are not even ready for receiving the event -> no fragment UI update! Or the event is triggered and received in the fragment, but the fragment is not ready for the UI update, cause it still hasn't inflated the layout -> NullpointerException Or the fragment receives the event, but is not attached to the activity anymore -> another Exception. There are ways to deal with single issues, but overall it is complicating the architecture a lot.

Somehow I tried a lot of things (playing around with Otto bus) but somehow I can't find any architecture which is working for making a central datasource available to all activities and fragments in the app.

How do you supply your fragments with data if you don't want to use bundles?

stoefln
  • 14,498
  • 18
  • 79
  • 138
  • You have a push model, where you're trying to feed data to the fragments. This is what appears to be the problem here. Basically a race-condition, If the fragment wins, everything is good. if the Activity wins, the problem appears. Have you tried a combination of pull/push model, where both parties (activity and fragment) can pull or push the data, based on other's availability. Also, for pull from fragment you might want to use public void onActivityCreated (Bundle savedInstanceState). – Gaurav Arora Oct 06 '14 at 14:42

1 Answers1

0
  • First of all a Fragment should be independent from other parts of an app. Moreover it shouldn't know parent activity: getActivity method should return just an Activity which could be casted to some interface.
  • an Activity shouldn't be a "data downloader". Basically activity is a View which receives various system and user events and displays particular state. For instance when the system creates activity it calls method 'onCreate' where activity should create/arrange fragments and views.
  • there is should be some manager or controller(call it as you wish) which knows where and how to get data for views. For instance if there is no internet connection it loads data from local database otherwise it makes network request.

So roughly speaking flow should look like this:

  1. fragment(or activity) has reference to the DataManager. The fragment subscribes on FeedDataEvent in the onResume method. When fragment wants(onResume method for example) to show some data to the user it calls DataManager.loadFeed() and displays to the user "loading..."
  2. DataManager checks if there is Task which is loading data from network. If there is no such fast it starts it.
  3. When data is downloaded DataManager emits FeedDataEvent.
  4. If the fragment is still visible it receives that event and shows data. If the user left the app fragment unsubscribed(in the onStop method) from FeedEventData and will not receive that event.

There is subtle thing with requests caching(making network request on every onResume is not very good idea) but it depends on particular app.

PS Almost all this things are implemented in RoboSpice and some other libraries.

eleven
  • 6,779
  • 2
  • 32
  • 52