How to Get the Result of Onpostexecute() to Main Activity Because Asynctask Is a Separate Class

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 can i to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

Your are starting a new AsyncTask in this line:

new ProductConnect().execute(true);

you should execute your asyncTask change that line with this:

asyncTask.execute(true);

How to get result on onPostExecute from a separate Asynctask class to another fragment class?

You are not adding your Movie item in movieModelList. That's why it remains empty. You have to modify like -

movieModelList= new ArrayList<>();
//adding JSON Array data into MovieModel Class object
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject finalObject = jsonArray.getJSONObject(i);
MovieModel movieModel = new MovieModel();
movieModel.setId(finalObject.getInt("id"));
movieModel.setTitle(finalObject.getString("title"));
movieModel.setPoster_path(finalObject.getString("poster_path"));


movieModelList.add(movieModel); //Add this line




}

Also, You have to set or refresh the adapter in your processFinish() callback.
Because ForecastTask will run in different thread and is asynchronous.

 @Override
public void processFinish(List<MovieModel> movieModels) {
this.movieModels=movieModels;
customAdapter = new CustomAdapter(getActivity(), movieModels);
gridView.setAdapter(customAdapter);
}

return value after run another AsyncTask in onPostExecute()

Problem: You want to pass the array list from the second AsyncTask back to MainActivity.

Solution: Passing activity instance to the first AsyncTask, then forward the instance to the second AsyncTask.

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Pass `this` as activity instance to the first AsyncTask.
DownloaderGet downloaderGet = new DownloaderGet(this, "http://xxxxx.php");
downloaderGet.execute();
}

public void onDataAvailable(List<String> arrauList) {
// Process array list here.

}
}

// The first AsyncTask.
class DownloaderGet extends AsyncTask<Void, Void, String> {
private WeakReference<MainActivity> activity;
private String url;

DownloaderGet(MainActivity activity, String url) {
this.activity = new WeakReference<>(activity);
this.url = url;
}

@Override
protected String doInBackground(Void... voids) {
// Your code here
// ...
return null;
}

@Override
protected void onPostExecute(String jsonData) {
// Forward the instance to the second AsyncTask.
new DataParserGet(activity.get(), jsonData).execute();
}
}

class DataParserGet extends AsyncTask<Void, Void, Boolean> {
private WeakReference<MainActivity> activity;
private String jsonData;

DataParserGet(MainActivity activity, String jsonData) {
this.activity = new WeakReference<>(activity);
this.jsonData = jsonData;
}

@Override
protected Boolean doInBackground(Void... voids) {
// Your code here
// ...
return null;
}

@Override
protected void onPostExecute(Boolean result) {
if (result) {
myNewArrayList = spacecrafts;
if (activity.get() != null) {
// Pass the array list back to main activity.
activity.get().onDataAvailable(myNewArrayList);
}
}
}
}

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

How to get a value from onPostExecute() to if I have a separate class that extends an AsyncTask class?

You can achieve this will callback listener.

public class Connector extends AsyncTask<String,Void,String>{
private OnPostExecuteListener onPostExecuteListener;
/**
* The callback interface
*/
public interface OnPostExecuteListener {
void onPostExecute(String result);
}

public void setOnPostExecuteListener(OnPostExecuteListener listener){
this.onPostExecuteListener = listener;
}

@Override
protected void onPostExecute(String result) {
result = "{ \n \"Data\": \n " + result + " \n }";
if(onPostExecuteListener !=null){
onPostExecuteListener.onPostExecute(result);
}
this.setJSON(result);
}

}

In your fragment class

public class CollegeBulletinListFragment extends Fragment implements OnClickListener, Connector.OnPostExecuteListener {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Connector connect= new Connector(getActivity().getApplicationContext(),colval,secondFlag);
connect.setOnPostExecuteListener(this); // set callback listener
connect.execute("");
}

@Override
public void onPostExecute(String result){
// do something with onPostExecute result.
}

}


Related Topics



Leave a reply



Submit