Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

I have this two classes. My main Activity and the one that extends the AsyncTask, Now in my main Activity I need to get the result from the OnPostExecute() in the AsyncTask. How can I pass or get the result to my main Activity?

Here is the sample codes.

My main Activity.

public class MainActivity extends Activity{      AasyncTask asyncTask = new AasyncTask();      @Override     public void onCreate(Bundle aBundle) {         super.onCreate(aBundle);                      //Calling the AsyncTask class to start to execute.           asyncTask.execute(a.targetServer);           //Creating a TextView.         TextView displayUI = asyncTask.dataDisplay;         displayUI = new TextView(this);         this.setContentView(tTextView);      }  } 

This is the AsyncTask class

public class AasyncTask extends AsyncTask<String, Void, String> {  TextView dataDisplay; //store the data   String soapAction = "http://sample.com"; //SOAPAction header line.  String targetServer = "https://sampletargeturl.com"; //Target Server.  //SOAP Request. String soapRequest = "<sample XML request>";        @Override protected String doInBackground(String... string) {  String responseStorage = null; //storage of the response  try {       //Uses URL and HttpURLConnection for server connection.      URL targetURL = new URL(targetServer);     HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();     httpCon.setDoOutput(true);     httpCon.setDoInput(true);     httpCon.setUseCaches(false);      httpCon.setChunkedStreamingMode(0);      //properties of SOAPAction header     httpCon.addRequestProperty("SOAPAction", soapAction);     httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");      httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());     httpCon.setRequestMethod(HttpPost.METHOD_NAME);       //sending request to the server.     OutputStream outputStream = httpCon.getOutputStream();      Writer writer = new OutputStreamWriter(outputStream);     writer.write(soapRequest);     writer.flush();     writer.close();       //getting the response from the server     InputStream inputStream = httpCon.getInputStream();      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));     ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);      int intResponse = httpCon.getResponseCode();      while ((intResponse = bufferedReader.read()) != -1) {         byteArrayBuffer.append(intResponse);     }      responseStorage = new String(byteArrayBuffer.toByteArray());       } catch (Exception aException) {     responseStorage = aException.getMessage();      }     return responseStorage; }  protected void onPostExecute(String result) {      aTextView.setText(result);  }         }    
like image 468
Stella Avatar asked Sep 25 '12 01:09

Stella


People also ask

Which method of the AsyncTask class can be used to achieve the same?

Methods of AsyncTask we can directly comminicate background operation using on doInBackground() but for the best practice, we should call all asyncTask methods . doInBackground(Params) − In this method we have to do background operation on background thread.

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.

How can I use AsyncTask in different activities in android?

Asynctask gives us the liberty to perform heavy tasks in the background and keep the UI thread light thus making the application more responsive and fast. AsyncTask class is used to do background operations that will update the UI(user interface).

When and on what thread does an AsyncTask onPostExecute method run?

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .


2 Answers

Easy:

  1. Create interface class, where String output is optional, or can be whatever variables you want to return.

     public interface AsyncResponse {      void processFinish(String output);  } 
  2. Go to your AsyncTask class, and declare interface AsyncResponse as a field :

     public class MyAsyncTask extends AsyncTask<Void, Void, String> {    public AsyncResponse delegate = null;       @Override      protected void onPostExecute(String result) {        delegate.processFinish(result);      }   } 
  3. In your main Activity you need to implements interface AsyncResponse.

     public class MainActivity implements AsyncResponse{    MyAsyncTask asyncTask =new MyAsyncTask();     @Override    public void onCreate(Bundle savedInstanceState) {        //this to set delegate/listener back to this class       asyncTask.delegate = this;        //execute the async task        asyncTask.execute();    }     //this override the implemented method from asyncTask    @Override    void processFinish(String output){       //Here you will receive the result fired from async class        //of onPostExecute(result) method.     }   } 

UPDATE

I didn't know this is such a favourite to many of you. So here's the simple and convenience way to use interface.

still using same interface. FYI, you may combine this into AsyncTask class.

in AsyncTask class :

public class MyAsyncTask extends AsyncTask<Void, Void, String> {    // you may separate this or combined to caller class.   public interface AsyncResponse {         void processFinish(String output);   }    public AsyncResponse delegate = null;      public MyAsyncTask(AsyncResponse delegate){         this.delegate = delegate;     }      @Override     protected void onPostExecute(String result) {       delegate.processFinish(result);     } } 

do this in your Activity class

public class MainActivity extends Activity {       MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){           @Override      void processFinish(String output){      //Here you will receive the result fired from async class       //of onPostExecute(result) method.      }   }).execute();   } 

Or, implementing the interface on the Activity again

public class MainActivity extends Activity      implements AsyncResponse{            @Override     public void onCreate(Bundle savedInstanceState) {          //execute the async task          new MyAsyncTask(this).execute();     }            //this override the implemented method from AsyncResponse     @Override     void processFinish(String output){         //Here you will receive the result fired from async class          //of onPostExecute(result) method.     } } 

As you can see 2 solutions above, the first and third one, it needs to create method processFinish, the other one, the method is inside the caller parameter. The third is more neat because there is no nested anonymous class.

Tip: Change String output, String response, and String result to different matching types in order to get different objects.

like image 77
HelmiB Avatar answered Oct 06 '22 01:10

HelmiB


There are a few options:

  • Nest the AsyncTask class within your Activity class. Assuming you don't use the same task in multiple activities, this is the easiest way. All your code stays the same, you just move the existing task class to be a nested class inside your activity's class.

    public class MyActivity extends Activity {     // existing Activity code     ...      private class MyAsyncTask extends AsyncTask<String, Void, String> {         // existing AsyncTask code         ...     } } 
  • Create a custom constructor for your AsyncTask that takes a reference to your Activity. You would instantiate the task with something like new MyAsyncTask(this).execute(param1, param2).

    public class MyAsyncTask extends AsyncTask<String, Void, String> {     private Activity activity;      public MyAsyncTask(Activity activity) {         this.activity = activity;     }      // existing AsyncTask code     ... } 
like image 45
quietmint Avatar answered Oct 05 '22 23:10

quietmint