Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onCreateView() wait for AsyncTask to execute?

Here is my situation:

In my onCreate(), I would like to create an AsyncTask to retrieve data for a server and store it in an ArrayList.

Then in my onCreateView(), I would like to put that data in a ListView, set an onItemClickListener, etc...

The problem is that I am creating a race between the AsyncTask and the UI thread. If the onCreateView() is called before the AsyncTask is done retrieving, then I do not set the adapter correctly, do not set the onItemClickListener, etc...

I would like some way to make sure that I wait for the AsyncTask to finish executing before starting the onCreateView() function. Is this possible? I read about using get() on the task, but I had some trouble executing it. It didn't seem to be doing anything.

The reason I would like to retrieve the data in onCreate() and set the adapter in onCreateView() (instead of setting the adapter in onPostExecute() of the AsyncTask), is that I would like to retrieve the data once, and be able to just create the view if the user rotates the screen or navigates back to that Fragment.

like image 281
user2085335 Avatar asked Feb 21 '13 00:02

user2085335


2 Answers

Here is a better way. Initialize your ListView and start your AsyncTask in onCreate(). Once data is available from the server, you add it to the same array which was given to your adapter and call notifyDatasetChanged() of your adapter, which takes care of populating your list view. Here you can use ListFragment as well in which you can call setEmptyText() to add text that is displayed if your list is empty.

like image 73
sujith Avatar answered Oct 10 '22 11:10

sujith


You should follow @sujith's answer and change your implementation, but here is an answer to your specific question:

I would like some way to make sure that I wait for the AsyncTask to finish executing before starting the onCreateView() function. Is this possible?

Yes this is possible, but it will prevent your UI from displaying while it is waiting for the task to finish.

Create and execute your AsyncTask then hold on to the reference to it:

MyAsyncTask mTask;

...
...onCreate()
mTask = new MyAsyncTask();
mTask.execute();
...
...onCreateView()
myInfo = mTask.get();
super.onCreateView().

In your case this is a bad idea, however, there are times when you may need to do something like this.

EDIT: mTask.get() will return whatever is returned by the doInBackground()

like image 39
Matt Avatar answered Oct 10 '22 11:10

Matt