Return a Value from Asynctask in Android

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 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.
}

need to return value from AsyncTask

The result of the async task execution is the response object produced by execute_barcode_webservice(). However, don't think about the async task as something that will execute and return a value to you. Instead, inside the method onPostExecute() you must take the response object and process it (extract its values and display them in a list, or whatever you want to do with it). The async task is just a way to execute some code in a separate thread then go back to the main thread (the UI thread) and process the results, which is done in onPostExecute().

My suggestion: rewrite execute_barcode_webservice() to return a response object instead of a String (an object that can be null if the operation fails) and pass that object to the onPostExecute() method. You will have to change the async task to:

public class AsyncCallWS extends AsyncTask<String, Void, Object> {
@Override
protected Object doInBackground(String... params) {
Object response = null;
try {
response = execute_barcode_webservice(params[0], params[1]);
} catch (Exception e) {
// TODO: handle exception
}
return response;
}

@Override
protected void onPostExecute(Object response) {
if (response != null) {
// display results in a list or something else
}
}

AsyncTask: where does the return value of doInBackground() go?

The value is then available in onPostExecute which you may want to override in order to work with the result.

Here is example code snippet from Google's docs:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}

protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}

protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

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


Related Topics



Leave a reply



Submit