Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTask onPostExecute never gets called

I am not sure what I am doing wrong but onPostExecute never gets called.

  • Created a base class called BaseActivity.java
  • From my original Activity I extended this class.
  • Placed PostToOpenFeint class inside BaseActivity
  • Called it from the UI thread from the main activity my doing:

    new PostToOpenFeint.execute(); 

The onPreExecute(), doInBackground(..) gets triggered, but for some reason the onPostExecute never gets called.

Thank you in Advance!

Dave

 private class PostToOpenFeint extends AsyncTask<Void, Void, Void> {   /*    * (non-Javadoc)    *     * @see android.os.AsyncTask#doInBackground(Params[])    */   @Override   protected Void doInBackground(Void... params) {    // does all the work here    return null;   }     /*    * (non-Javadoc)    *     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)    */   @Override   protected void onPostExecute(Void result) {    // TODO Auto-generated method stub    super.onPostExecute(result);    Toast.makeText(MainScreen.this, "Done syncing", Toast.LENGTH_LONG).show();   }    /*    * (non-Javadoc)    *     * @see android.os.AsyncTask#onPreExecute()    */   @Override   protected void onPreExecute() {    // TODO Auto-generated method stub    super.onPreExecute();    Toast.makeText(MainScreen.this, "About to sync all your scores", Toast.LENGTH_LONG).show();   } 

Looking into it more, this is what I was able to observe. For example if I place this call:

 new PostToOpenFeint.execute(); 

right after onCreate of the Activity, then everything works fine. If I place this call say inside a button listener.

settingsButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) {    new PostToOpenFeint.execute(); } }); 

The onPostExecute() never gets called, not sure what I am doing wrong. The restriction I read was to call this from UI Thread and I am calling it from UI thread.

like image 201
ddavtian Avatar asked Dec 20 '10 22:12

ddavtian


People also ask

How do you know when AsyncTask is done?

Use getStatus() to get the status of your AsyncTask . If status is AsyncTask. Status. RUNNING then your task is running.

What is the problem with AsyncTask in Android?

In summary, the three most common issues with AsyncTask are: Memory leaks. Cancellation of background work. Computational cost.

Why did AsyncTask get deprecated?

This class was deprecated in API level 30. AsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes.

What happens to AsyncTask if activity is destroyed?

If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes. And when it completes, the AsyncTask won't update the UI of the new Activity.


2 Answers

I had a similiar problem just now. I was extending AsyncTask<Integer,Integer,Integer> and my onPostExecute method looked like:

protected void onPostExecute(int result) 

This seemed OK to me, but then again I'm more of a .NET guy than a Java guy. I changed it to:

protected void onPostExecute(Integer result) 

because for some reason Java thinks there is a difference between int and Integer?

I think that your problem is that you're declaring the return type as void in your:

extends<Void,Void,Void> 

That means no params, no progress and no result. If you want to execute something when it's done, I think you need to give it some kind of value like and integer or a boolean.

If you change your extends to:

<Void,Void,Integer> 

Now your passing no params, not publishing any progress, but are returning a value. Change your onPostExecute method to accept an Integer:

protected void onPostExecute(Integer result) 

Then change the return in your doInBackground method to something like:

return 1; 

Then it should execute for you.

like image 95
Tom E. Avatar answered Oct 04 '22 10:10

Tom E.


There's one more gotcha about AsyncTasks that I just spent half the day on:

The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.

Says the documentation. On Gingerbread (and probably before), given the right circumstances, this leads to onPostExecute not being run. The solution, however, is easy, just a

new MyAsyncTask(); 

early in the UI thread so the class gets loaded before anything in the background can inadvertently load it.

I had used a static function in my AsyncTask subclass from a background thread that, depending on timing, got called before anything on the UI thread used that AsyncTask subclass, and bingo, a nice Heisenbug.

(Bear with me for answering this old, already answered question, but I didn't find that tidbit of info anywhere, and this is my first post)

like image 44
Christian Mock Avatar answered Oct 04 '22 10:10

Christian Mock