0

I have the following AsyncTask class which I want to handle multiple api calls and return a List back to my activity. I am having a problems trying to make this work.

How can I return an object back to my activity when onPostExecute() method does not return anything?

public class NetworkCall extends AsyncTask<Call, Void, List<Student>> {

@Override
protected List<Students> doInBackground(Call... calls) {
    try {
        Call<Students> call = calls[0];
        Response<Students> response = call.execute();
        return response.body().getStudents();

    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
    }

    @Override
    protected void onPostExecute(List<Students> students) { 

    }
}
George
  • 6,886
  • 3
  • 44
  • 56
Struggler
  • 1
  • 2
  • Possible duplicate of [How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?](https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a) – medyas Feb 10 '19 at 12:59
  • Yes, however that was asked 6 years 4 months ago so I was thinking there might be other ways to achieve this now. – Struggler Feb 10 '19 at 13:03
  • its the same, did not change you will be using an interface to communicate with you activity – medyas Feb 10 '19 at 13:07

2 Answers2

0

One of the options is to create interface and use as callback. In async task class :

public class NetworkCall extends AsyncTask<Call, Void, List<Student>> {

public interface NetworkCallback{
    void onResponse(List<Students> students);
}

private NetworkCallback callback;

public void setCallback(NetworkCallback callback){
    this.callback = callback;
}

@Override
protected List<Students> doInBackground(Call... calls) {
    try {
        Call<Students> call = calls[0];
        Response<Students> response = call.execute();
        return response.body().getStudents();

    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
    }

    @Override
    protected void onPostExecute(List<Students> students) { 
        callback.onResponse(students)
    }
} 

and now in your activity implement the interface and provide to the async task via setter.

public class StudentsActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //.... you setup for activity

    NetworkCall networkCall = new NetworkCall();
    networkCall.setCallback(new NetworkCall.NetworkCallback() {
      @Override
      public void onResponse(List<Students> students) {
        //update your UI here
      }
    });
  }
}

Based on the Docs onPostExecute runs on the main UI thread so no need to the runOnUiThread and Runnable

medyas
  • 1,166
  • 13
  • 21
Maksim Novikov
  • 835
  • 6
  • 18
  • Thanks for your reply. I don't fully understand this but I will try it out. Could you add the code i would need in the activity please? – Struggler Feb 10 '19 at 13:10
0

you can implement like this:

Your interface:

public interface OnTaskCompleted{
  void onTaskCompleted(Object o);
}

Your Activity:

public class YourActivity implements OnTaskCompleted{
// your Activity

@Override
void onTaskCompleted(Object o){

}

And your AsyncTask:

public class 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(o);
   }
}