Make HTTP requests in Fragment onCreateView, onCreate or onActivityCreated? - android

I use Navigation Tabs in my app. I have 3 fragments which load different data from Internet. I want to know the best place where to put the code that make the HTTP request, in onCreate, onCreateView or onActivityCreated?
Usually, I put all the code (requesting data, populating adapter, inflating view...) in onCreateView. I also saw many people doing it on Internet.
But this guide https://github.com/thecodepath/android_guides/wiki/Creating-and-Using-Fragments do things differently. So I want to be sure on what to do exactly.

I would normally put the code to refresh the view with new states in the onResume(). I would only inflate the view in onCreateView and possibly set adapters and such.
It also depends on how fresh you want the data. I you only need to load it when the user starts the app, I would load it in the onCreate of the Activity and then load all data for the fragments in one batch. You can then store the data and retrieve it in the different fragments.
Also you always want to load data from the internet on a different thread. If you are set on loading the data in the fragment itself, I would start an asynctask in the onCreate and refresh the view for the fragment in the callbacks from the asyntask. In the onCreateView you can put default values, or let the user know the data is comming via text or some other notification.
If you want real fresh data you can start the asynctask in onResume() of the fragment.

Answering really late, but if you are making HTTP Requests, I would suggest putting them in onActivityCreated(). onCreateView is great for initialising and binding your views. onActivityCreated is called once this is done and onCreateView returns, as you can see in the answers to this SO question.
You can read more about this here and here on SO.

Related

Is it possible to call make network call for fragment from an activity

I am following MVP approach, and I have an activity containing 4 fragments. On App launch activity makes network call, and passes data to fragments.
In one of fragment i have recycler view, and it has Swipe to Refresh.
When user swipe to refresh i need to make network call from fragment, which i learnt is not a good idea, and also i am following MVP approach, so activity has the list of methods to execute in presenter, and presenter decided whether to grab data from local repository or remote.
So what should i do to perform swipe to refresh operation from a fragment.
Should i call activity method, and perform network call from there, and re pass the updated data to fragment, or is it fine to make a network call from fragment.
The answer is neither the Activity nor the fragment. The fragments and activities shall never "fetch" or "handle" data. Only display data. And deal with activity lifecycle with regards to this.
If you want to know further this will be a good read for you.

Set data from Activity to it's Fragment at runtime on data updated from server

I have another one question about transfering data from Activity to Fragment.
In my activity I have next situation: one part of UI is situated in Activity, and another (more dynamic part) is situated in Fragment.
The data which I need to populate my UI elements in Activity and Fragment is on server. To get that data, I am sending request to
server in Acvitity's onCreate() method. In Activity's callback method: void onDataLoaded(List<MyObject> dataList) I get data from server.
And in this method I am creating my Fragment and setup data to it. I am passing data to it through the Bundle object duding creation. Everything
is ok with this. But the issue is in next: on network reconnect I need to load data from server to be sure that all data is up to date. And of course I
need to reinitialize data in Activity and Fragment. But I don't want to fully RE-CREATE fragment. I want just to setup new data to it's fields.
How can I do that properly? Is it a good way to to keep reference in my Activity to that Fragment and call some public method: myFragment.SetMyCustomData(List<MyObject> dataList) ?
I understand that the best way to load data from server in my fragments onCreate() method, but I can't split it into two API calls and I need that data in Activity as well.
Thanks.
Well this is not a transfering problem . Anyway you can use Event Bus for easier communication from Activity to Fragment and vice-versa. It is very easy to use . And as for your problem I belive you are not doing what you need in the right time .
https://github.com/greenrobot/EventBus

When (& where) are my fragments created

I'm using the viewpagerindicator library (http://viewpagerindicator.com/) to create some sort of wizard for my android app. It works fine and does exactly what I want.
I would like to "extend" the functionality a bit by having "previous"/"next" buttons in my ActionBar - pretty much as in Android's "Done Bar" tutorial - to step through the wizard. Works like a charm, too.
HOWEVER:
I would like to display information about the "next" & "previous" fragment in the ActionBar's buttons. Information I pass to the fragments that live in the ViewPager at the time of their "creation" (actually at the time of their object instantiation - using the classical "newInstance(...)" approach to create the instance of my fragment, store the parameters in a Bundle and extract them in the fragment's "onCreate" method). The same way the template does it, when you create a new fragment for your project.
So, this information is the thing I actually want to display in my wizards button to know what fragment is next and which was last.
The type of this information is not important for my problem. It could be a String or an icon or an int or ... anything else you want.
However, wherever I've tried to access my fragments data, the fragment has not yet been fully initialized (meaning its "onCreate" method has not been called yet).
I've tried it in the host fragment's "onViewCreated" method, because I thought that's where all its subviews should be initialized already (at least their "onCreate" method should have been called, I thought), but it seems that this is handled differently for ViewPager to retain only the number of fragments in memory that was set by setOffscreenPageLimit.
So, what I'm looking for (and probably just missing) is the correct callback method here. One that is called when the ViewPager's next Fragments have been loaded and initialized. If such a callback exists, I could place my little piece of code there to update the text in my "previous"/"next" buttons within the ActionBar.
Any help, comments, ideas are highly appreciated. If needed, I can also try to attach some code sample to better explain my setup, but I think it should be easy enough to understand what my problem is.
Thanks in advance!
P.S.: I also tried to do this by using EventBus to send "onFragmentInitialized" messages from my fragments within in the ViewPager and the hosting fragment. It actually worked, but it does not seems the proper way to do this.
When a Fragment's onCreate Method is called, its already preparing to be displayed, and practically its past the point where its considered a Next or Previous fragment instead its considered current.
A fragment's onCreateViews method is called after committing a transaction in the FragmentManager. which takes less than 1 sec to bring it in front of the user (depending on the device and runtime environment)
But in your case, your data should be initalized outside the Fragment that uses it, and displayed where ever you want by passing the data itself then displaying whatever you want form it.
decouple your data from android objects (Fragment, Activity ...) and you should be able to load, maintain, access it cleanly and without worrying about their callbacks.
The Fragment's arguments can be read and loaded in its onAttach callback rather than onCreate, the Activity will then (after onAttach is complete) get a onAttachFragment callback with the Fragment as a parameter. However, I doubt onAttachFragment will be called when switching between already loaded pages in the view pager.
If not, you could have the fragment notify the activity (through an interface) that it is now active during its onActivityCreated, onViewCreated or similar method.
But it sounds more like the activity should register as a page changed listener to the ViewPager itself, and update its state depending on the page rather than which fragment is active.
As a side note, ViewPagerIndicator is quite old now (hasn't been updated in 3 years), a more modern approach is the SlidingTabs example from Google, which has been built into a library available here: https://github.com/nispok/slidingtabs

Asynctask in Fragment or Parent Activity?

I have a scenario and I an not sure on what path to go.
Scenario
The app has a Home activity which displays various fragments. The data in the fragments can come either from the web or a local database and is retrieved using an asynctask.
From what I saw, I have 2 alternatives:
Put the Asynctask in parent activity and then use fragment.newInstance(parameters) to pass the result to the fragment. However, if in my asynctask I need to update the progress or some info on the fragment, each time I will have to call newInstance with the new set of parameters.
Add the fragment and put the asynctask in it, in this way when progress is needed, I can update the fragment's views, as I have access to them + when the asynctask is done, I can populate the list with the info.
What would be the correct approach ?
LE: actually for point 1 in order to update the fragment I can call fragment's public methods after I find it with findFragmentById in the parent activity
A better way if you have multiple tasks would be to use an IntentService :
http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/
You would have a better control to what you're requesting and what you want to cancel.
I would go with the second approach.
My primary reason though would be to avoid the issues that can happen on screen orientation change while the AsyncTask is working.
I would go with method 2, but take it a step further.
Have a separate fragment to run your async task. This way, you can handle any configuration changes (not just rotating screen) without any issues.
In another fragment, you can display the data. You can pass the data from your async task fragment via callbacks to the activity, and have the activity call a method in the display fragment to update the data.

Completing fragment transaction when a task is done

It might be an easy question but I have been working on it for hours and couldn't solve it. Sorry if it was asked before.
In my activity I have 2 Fragments. In one fragment I am getting JSON from server and putting in ArrayList. After putting in ArrayList I have to add another fragment passing first value in ArrayList.
Here is the problem, I want to add Fragment when my ArrayList is completed, after it got all values from server. I am making service call in my onActivityCreated() method, server call is happening in another class and I am getting Bundle in a method called onRequestFinished() and I am putting JSON to ArrayList in this Overridden method.
P.S. I tried to put AsyncTask but I couldn't make it since I have to wait the response from onRequestFinished() method.
How can I handle it and complete Fragment Transaction after filling my ArrayList?
Thanks
I suggest using startActivityForResult in the first fragment. When the parent activity receives the onActivityResult it can then start the second fragment. There are plenty of examples of how to do this on SO and elsewhere.
Even if you do not want to start an activity, you can use the same mechanism to communicate back to the activity when your first fragment has completed e.g.:
Is there a method that works like start fragment for result?
Alternatively you could of course just implement a callback mechanism from your first fragment - but personally, I like the onActivityResult approach.

Categories

Resources