How to Send Data Back from Onpostexecute in an Asynctask

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

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);
}

AsyncTask - How to pass value back to activity class after onPostExecute?

Method 1 is the basic, anonymous inner class implementation. Because of the inner AsyncTask class is not static class, you can access to the CustomActivity's properties from that implementation.

In Method 2, AsyncClass implemented separately. If you gave your activity to this class, it can be call back your desired method after execution. This method, for our example is the #setChangedData method. CustomAsyncTask call backs the #setChangedData in the #onPostExecute.

public class CustomActivity extends AppCompatActivity {

String mChangedData;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Method 1 - change data into the anonymously implemented AsyncTask class
new AsyncTask<Integer, Void, Void>() {

@Override
protected Void doInBackground(Integer... params) {
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
CustomActivity.this.mChangedData = "foo"; // this changes mChangedData as "foo"
}
}.execute(1);

// Method 2 - change data into the custom AsyncTask class
new CustomAsyncTask(this).execute(2);
}

public void setChangedData(String changedData){
this.mChangedData = changedData;
}

static class CustomAsyncTask extends AsyncTask<Integer, Void, Void> {
CustomActivity mActivity;
public CustomAsyncTask(CustomActivity activity) {
this.mActivity = activity;
}
@Override
protected Void doInBackground(Integer... params) {
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mActivity.setChangedData("bar");
}
}
}

And, as method 3, if you want to separate you Activity and AsyncTask more loosely, this is the handler method:

public class CustomActivity extends AppCompatActivity {

private String mChangedData;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

CustomAsyncTask task = new CustomAsyncTask();
task.setOnDataChangedListener(new CustomAsyncTask.OnDataChangedListener() {
@Override
public void onDataChanged(String data) {
mChangedData = data;
}
});
task.execute(1);
}

private static class CustomAsyncTask extends AsyncTask<Integer, Void, Void> {

private OnDataChangedListener onDataChangedListener;
@Override
protected Void doInBackground(Integer... params) {
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(onDataChangedListener != null) {
onDataChangedListener.onDataChanged("foo");
}
}

void setOnDataChangedListener(OnDataChangedListener onDataChangedListener) {
this.onDataChangedListener = onDataChangedListener;
}

interface OnDataChangedListener {
void onDataChanged(String data);
}
}
}

Return value from AsyncTask class onPostExecute method

I guess you are trying to read class A variable before it is being set..
Try to do it using callbacks..in the callback function pass the values and refresh your spinners..

You can create interface, pass it to AsyncTask (in constructor), and then call method in onPostExecute

For example:

Your interface:

public interface OnTaskCompleted{
void onTaskCompleted(values);
}

Your Activity:

public YourActivity implements OnTaskCompleted{
//your Activity
YourTask task = new YourTask(this); // here is the initalization code for your asyncTask
}

And your AsyncTask:

public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
private OnTaskCompleted listener;

public YourTask(OnTaskCompleted listener){
this.listener=listener;
}

//required methods

protected void onPostExecute(Object o){
//your stuff
listener.onTaskCompleted(values);
}
}

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

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.

How do i return a result from a async task

I would personally add a callback to your class, then once onPostExecute is run, fire off your callback to the listener on the main class.

class GetDataFromServer extends AsyncTask<String, String,JSONObject>
{
// Progress Dialog
private ProgressDialog qDialog;
private Context context;
private String dialogString;
private ArrayList<String[]> newLoginResult;
private InformComplete myCallback;

public GetDataFromServer(String dialogMessage, Context con,InformComplete callback)
{
this.qDialog = new ProgressDialog(con);
this.dialogString = dialogMessage;
this.context = con;
this.myCallback=callback;
}

@Override
protected void onPreExecute()
{
// set up your dialog
}

@Override
protected JSONObject doInBackground(String... args)
{
JSONObject jsonNewUser=new JSONObject();
return jsonNewUser;
}

public void onPostExecute(JSONObject jsonString)
{
qDialog.dismiss();
myCallback.PostData(jsonString);
}
public interface InformComplete
{
public void PostData(JSONObject result);
}
}

Then from your calling class, you'd have something like this...

    private void callTheAsyncThing
{
GetDataFromServer gds=new GetDataFromServer("please wait", this, letMeKnow);
gds.execute(params);
}

private InformComplete letMeKnow=new InformComplete()
{
public void PostData(JSONObject result)
{
// we now have the data in the calling class
}
};


Related Topics



Leave a reply



Submit