Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do i send data back from onPostExecute in an AsyncTask?

my issue is the same as this Instance variable of Activity not being set in onPostExecute of AsyncTask or how to return data from AsyncTask to main UI thread but i want to send the data back to the same calling activity. Doesnt startActivity for intents always restart the activity

like image 366
skinnybrit51 Avatar asked Feb 25 '12 20:02

skinnybrit51


People also ask

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.

When AsyncTask is executed it goes through what steps?

An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .

How do I use AsyncTask?

Android AsyncTask going to do background operation on background thread and update on main thread. In android we cant directly touch background thread to main thread in android development. asynctask help us to make communication between background thread to main thread.

What happen if we call execute more than once in AsyncTask?

Limitation Of AsyncTask There is a limit of how many tasks can be run simultaneously. Since AsyncTask uses a thread pool executor with max number of worker threads (128) and the delayed tasks queue has fixed size 10. If you try to execute more than 138 AsyncTasks the app will crash with java.


2 Answers

On option is to use listeners, where you create an interface that your activity implents, something like:

public interface AsyncListener {
    public void doStuff( MyObject obj );
}

That way, if you're subclassing AsyncTask, it is easy to add this listener, then in onPostExecute(), you could do something like:

protected void onPostExecute( MyObject obj ) {
   asyncListener.doStuff(obj);
}
like image 82
Mike D Avatar answered Oct 22 '22 18:10

Mike D


This depends on your class structure, but if your AsyncTask is a class within your Activity then you can reference methods of that activity. What you would do is in your onPostExecute method call a function of your Activity that passes some data that was retrieved in the AsyncTask to the activity where you can then use it..

The code would look like this

class YourActivity extends Activity {
   private static final int DIALOG_LOADING = 1;

   public void onCreate(Bundle savedState) {
     setContentView(R.layout.yourlayout);
     showDialog(DIALOG_LOADING);     
     new LongRunningTask1().execute(1,2,3);

   } 

   protected Dialog onCreateDialog(int dialogId) {
     switch(dialogId) {
       case DIALOG_LOADING:
           ProgressDialog pDialog = new ProgressDialog(this);
           pDialog.setTitle("Loading Data");
           pDialog.setMessage("Loading Data, please wait...");
           return pDialog;
        default:
            return super.onCreateDialog(dialogId);
      }      
   }

   private void onBackgroundTaskDataObtained(List<String> results) {
      dismissDialog(DIALOG_LOADING);
     //do stuff with the results here..
   }

   private class LongRunningTask extends AsyncTask<Long, Integer, List<String>> {
        @Override
        protected void onPreExecute() {
          //do pre execute stuff
        }

        @Override
        protected List<String> doInBackground(Long... params) {
            List<String> myData = new ArrayList<String>(); 
            for (int i = 0; i < params.length; i++) {
                try {
                    Thread.sleep(params[i] * 1000);
                    myData.add("Some Data" + i);
                } catch(InterruptedException ex) {
                }                
            }
            return myData;
        }

        @Override
        protected void onPostExecute(List<String> result) {
            YourActivity.this.onBackgroundTaskDataObtained(result);
        }    
    }

}

So the typical flow is like this, set the view of the current page, and then show a progress dialog. Right after that start the async task (or whenever, it doesn't matter really).

After your async task is complete, call a function of the activity and pass it the data. Don't use shared data within the async task or you risk issues with threading.. Instead once you are done with it pass it to the activity. If you want to update the view progressively while doing work you can use on onProgressUpdate

like image 24
Matt Wolfe Avatar answered Oct 22 '22 18:10

Matt Wolfe