Return Value from Asynctask Class Onpostexecute Method

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

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

Return a value from AsyncTask in Android

Why not call a method that handles the value?

public class MyClass extends Activity {

private class myTask extends AsyncTask<Void, Void, Void> {

//initiate vars
public myTask() {
super();
//my params here
}

protected Void doInBackground(Void... params) {
//do stuff
return null;
}

@Override
protected void onPostExecute(Void result) {
//do stuff
myMethod(myValue);
}
}

private myHandledValueType myMethod(Value myValue) {
//handle value
return myHandledValueType;
}
}

How do I return value from AsyncTask class to another class?

AsyncTask is called async for a reason.

In the following code you execute your AsyncTask and then immediately try to access one of its fields:

FetchZipTask fzt = new FetchZipTask();
fzt.execute(location);
loc = fzt.locale;

That won't work because FetchZipTask may still be running when you're trying to access its locale variable.

onPostExecute() is called when the task is finished, so you should pass your result from there.

You could define an interface in FetchZipTask, pass an instance of it as a constructor param and call the appropriate method on that instance in onPostExecute():

public class FetchZipTask extends AsyncTask<String, Void, String> {
// declaring a listener instance
private OnFetchFinishedListener listener;

// the listener interface
public interface OnFetchFinishedListener {
void onFetchFinished(String result);
}

// getting a listener instance from the constructor
public FetchZipTask(OnFetchFinishedListener listener) {
this.listener = listener;
}

// ...

// calling a method of the listener with the result
@Override protected void onPostExecute(String result) {
listener.onFetchFinished(result);
}
}

In your Activity, pass an OnFetchFinishedListener when instantiating your AsyncTask:

new FetchZipTask(new FetchZipTask.OnFetchFinishedListener() {
@Override
public void onFetchFinished(String result) {
// do whatever you want with the result

Uri geoLocation = Uri.parse("geo:"+ result);
Log.d("Debug", geoLocation.toString());
Intent in = new Intent(Intent.ACTION_VIEW);
in.setData(geoLocation);
if (in.resolveActivity(getPackageManager()) != null) {
startActivity(in);
}
}
}).execute();

And that's it. Orientation change may still be a problem, so you could move your AsyncTask in a headless Fragment, or consider using a Service instead.

Returning a string onPostExecute() in Async class

I had the exact same problem a few months back now. Found this back then and it worked for me. Hope it helps!

Return value from AsyncTask class onPostExecute method

How to handle return value from AsyncTask

You can get the result by calling AsyhncTask's get() method on the returned AsyncTask, but it will turn it from an asynchronous task into a synchronous task as it waits to get the result.

String serverResponse = apiObj.execute(nameValuePairs).get();

Since you have your AsyncTask in a seperate class, you can create an interface class and declare it in the AsyncTask and implement your new interface class as delegate in the class you wish to access the results from. A good guide is here: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?.

I will attempt to apply the above link to your context.

(IApiAccessResponse)

public interface IApiAccessResponse {
void postResult(String asyncresult);
}

(ApiAccess)

public class ApiAccess extends AsyncTask<List<NameValuePair>, Integer, String> {
...
public IApiAccessResponse delegate=null;
protected String doInBackground(List<NameValuePair>... nameValuePairs) {
//do all your background manipulation and return a String response
return response
}

@Override
protected void onPostExecute(String result) {
if(delegate!=null)
{
delegate.postResult(result);
}
else
{
Log.e("ApiAccess", "You have not assigned IApiAccessResponse delegate");
}
}
}

(Your main class, which implements IApiAccessResponse)

ApiAccess apiObj = new ApiAccess (0, "/User");
//Assign the AsyncTask's delegate to your class's context (this links your asynctask and this class together)
apiObj.delegate = this;
apiObj.execute(nameValuePairs); //ERROR

//this method has to be implement so that the results can be called to this class
void postResult(String asyncresult){
//This method will get call as soon as your AsyncTask is complete. asyncresult will be your result.
}


Related Topics



Leave a reply



Submit