Fragments, Activities , and Data - android

I have an android application where I have an activity with two fragments. One with a map view and the other with a listview. In the main activity I get the user's gps and results from the database based off the gps and send that data to the fragments. That made since instead of calling inside the fragment twice the same data. However, a lot of times the request for the backend data and the gps coordinates of the user are not completed before the fragments are created.
I set up an interface to pass the data back and forth but need to find a way to pause the fragment creation until all data is there.
Any ideas? I can post code if neccesary.

Don't "pause" the fragment. Have a "loading" state, a "loaded" state, and an "error" state. Then show the user what is going on between each state.

You should not block the fragment UI until the data is ready, but instead you should show the user that the page is loading (e.g. with a Progress Bar).
Once the data is ready, you should populate the fragments with data (through a callback) or show an error message.

Thanks for the responses. I found a better way to do it. So I was passing data from the activity to fragment via an Interface and in the onAttach method of the fragment. Instead I created a Local Broadcast Manager that listens for the data to be complete in the activity class and sends to the map fragment to populate.
Hope this helps someone else.

Related

Recommended method to retrieve data to display (from an API) in an Android Fragment

If I need to display data coming from an API in a Fragment (using an AsyncTask), let's say a list of items in a RecyclerView, I believe it shouldn't be done in onCreate() or onCreateView() since theoretically the view elements are being initialized and may not be ready to use if the call to the API is faster. Am I correct?
(I assume it's kind of impossible to get a response from an API in less time than it takes for Android to create the view though).
There is onActivityCreated() and onStart() but I am still confused about when the parent Activity calls them.
The thing I want to avoid is reloading data (making a call to the API) if it's not necessary, for instance because of an orientation change or going back to this Activity after a click on the back button from a possible "next" Activity.
Thanks.
If it is your first "window" (Activity or whatever) the only way I know is showing a loading text, image, etc.
If it isn't your first view you can load your data in another window and store it to later usage when the user reaches the View to show the info.
You can load it right in your onCreate, onStart or so, but as you said probably you won't have time to download the info, so again, show a loading page or whatever you want while your data comes.
To avoid initialization errors call your AsyncTask after initializing the elements. And to avoid calling the API multiple times save your data locally while the app is opened, it depends on your app requirements

How to call the web service only once in android

I have three tabs in my view. Every time when I press the each tab some layout will be inflated and a web service call is done. I am populating some data into my inflated view through this web service call. Everything is working fine. But the problem is I don't want to call the web service every time when I press the tab for the second time. Previous data should be populated automatically without making a call to the web service. I don't think I can use onResume() method for this. Googled out many pages to find this answer but nothing is helpful. Please post the code if necessary. Thanks in advance.
These are my workarounds till now.
TabHost setCurrentTab only calls oncreate method for Activity in Tab once
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://jnastase.alner.net/archive/2010/10/27/handling-orientation-change-in-android.aspx
Your webservice should return some data, keep this data to your local memory and check every time either this data is null or not, if null then call service otherwise inflate from local data.
First of all, you should know the state of your 'call': not calling, pending, called. You must store it somewhere (activity, shared preferences, database etc) then making a call. Now, for data: you should implement some caching (again, in activity, shared preferences, database or even in plain files).
Then, in any state of a call, you can show data from cache, if it exists, and when call is done you can store new data in cache and show it.
whenever any changes made in one tab, store value in some variable, whenever next time the page is initialized, initialize with old selected value. Please try it out.. It may solve the problem..

Start activity while pulling data from database

I have an application which stores data in SQLite database. Main activity is just a screen with a single button. When user clicks this buton the second activity opens. The second activity is a list (ListActivity) which should contain all the records from database. Here is the question: which approaches fits better: 1) when button is clicked, start AsyncTask, in doInBackground method pull data from database and send pulled data to the second activity as a parcelable array or 2) start the second activity, in onCreate method pull the data from database and display progress bar while selecting data. I believe it is not based on primary opinion and there should be valuable pros and cons. But I am new to Android and I'm struggling to identify better approach for this. Thanks for your attention.
First approach is not user friendly. Because when user press a button to open different activity(In terms of UI), then user except to show a transition, Not the stuck in first activity. Actually it depend on your application UX design. Also first approach has another problem. If you load data in first activity then you have to transfer many data when you call another activity.
Use the slightly modified second approach. First start the second activity, then call the AsyncTask(in onCreate method) to load the data.
Well, I think the best is starting AsyncTask on clicking button and process data in doInBackground as You said. In onCreate() of second acivity display progress bar, and in doInBackground() send data and display items. It seems to be the best from point of performance.

Making data accessible to fragments

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?
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:
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..."
DataManager checks if there is Task which is loading data from network. If there is no such fast it starts it.
When data is downloaded DataManager emits FeedDataEvent.
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.

Wrong Fragment is loaded when resuming after my app was killed

In my App I have:
DataManager class - a singleton which holds data
Activity which shows a 'loading' fragment until the data is ready, and then once it is ready, it replaces it with a 'content' fragment. (I do this with the replace() method, since I no longer have use for the 'loading' fragment)
The following flow causes (sometimes) a null pointer exception:
Open app and wait for the data to be loaded (meaning, until we get to the 'content' fragment)
leave the app using the home button
open the app after a while (after Android kills the app)
What happens is that the app resumes to the 'content' fragment, but the data from the DataManager is null.
This happens because Android kills my app, but when I resume, it saves the state, meaning it shows the 'content' fragment automatically.
Is there a way for me to tell the app not to create the 'content' fragment in this scenario? The solution I currently have in mind is to create a 'loading' Activity instead of a fragment, but i'd like to avoid that.
What I would suggest is either:
Persist your data to disk (e.g. SQLite DB), rather than retaining it as static data.
In your Activity onCreate(), check if you have data. If you do, continue on. If not, remove the content fragment and add back the loading fragment.
I would suggest that in the content fragment before loading other views and all, check if your data is ready. if not then start the loading fragment and resume content fragment when it's ready.
e.g in OnCreate
if(!dataLoaded){
replaceFragment(LoadingFragment)
}

Categories

Resources