Asynctask: Where Does the Return Value of Doinbackground() Go

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

how to get the return value from my doInBackground task?

First, declare this asynctask class:

class MyTask extends AsyncTask<String,Void,Bitmap>{

@Override
protected Bitmap doInBackground(String... strings) {
String myString = Params[0];
try {
URL url = new URL(myString);
Bitmap myBitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
return null;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imgDisplay.setImageBitmap(bitmap);
}
}

Your zoomActivity changes to:

public class ZoomActivity  extends Activity {
ImageView imgDisplay;
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_zoom);

Intent intent = getIntent();
String url2 = intent.getStringExtra("image");

Button btnClose;

imgDisplay = (ImageView) findViewById(R.id.imgDisplay);
btnClose = (Button) findViewById(R.id.btnClose);

//call asynctask
new MyTask().execute(url2);

btnClose.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ZoomActivity.this.finish();
}
});

}

hope this works

Retrieving return statement from doInBackground method in AsyncTask?

Yes we can retrieve/catch the return statement from doInBackground() in onPostExecute() if write AsyncTask's class statement properly.

AsyncTask is a generic class that accepts three class type (non-primitive) parameters. Try below code to understand and get returned value from doInBackground() method.

I am expecting your Evaluate class' getScore() method's return type is int.

public class EvaluateTask extends AsyncTask<Void,Void,Integer> {

ProgressDialog progress = new ProgressDialog(context);

@Override
protected void onPreExecute() {

progress.setMessage("Analysing");
progress.setIndeterminate(true);
progress.show();
}

@Override
protected Integer doInBackground(Void... params) {
Evaluate evaluate = new Evaluate(db); //Evaluate class object
return evaluate.getScore();
}

@Override
protected void onPostExecute(Integer finalScore) {

// in this method, parameter "finalScore" is the returned value from doInBackground() method, that you can use now.
super.onPostExecute(finalScore);
progress.dismiss();
Intent i = new Intent(googleAct.this, result.class);
startActivity(i);

//I am considering you were expecting below finalScore as the returned value from doInBackground() method.
//Now there should not be an error.
i.putExtra("score", finalScore);
}
}

Return multiple values from AsyncTask/doInBackground and use it in other method

FOG

Simply implement onPostExecute inside your AsyncTask class :)

for example :

@Override
protected void onPostExecute(String makeValue) {
// remember this method gets called on main thread
letsCallFogsMethod(makeValue); //call your method and pass the make value here :)
}

Thats it buddy :)
Now how come this onPostExecute is getting any value???
You have to return it from doInBackground method dude :)

like

@Override
protected String doInBackground(String... params) {
//after all bra bla simply say
return obj.getMake();
}

Do you notice any change in your doInBackground signature buddy?? Yeah I changed from Void to String :)

By writing String you are informing that when you are done executing doInBackground you will return a string to onPostExecute :)

So if I write as it is in the answer will it work ?? Nope.
Given that you have specified Void in your doInBackground your Async task signature might look something like

private class FogsAsyncTask extends AsyncTask<bla,blah,Void> {

Can you see the last Void??? :) But now you have chnaged doInBackground isn't it so update the AsyncTask signature as well :)

private class FogsAsyncTask extends AsyncTask<bla,blah,String> {

Now it should work fine :) Happy coding buddy :) Hope my answer helped you :)

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

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

Return string from Asynctask

cant get the result out of doInBackground into onPostExecute

To return auth2 String from doInBackground :

1. Change return type of doInBackground method from Void to String:

 @Override
protected String doInBackground(Void... arg0) {

}

2. Change AsyncTask last generic type from Void to String :

private class GetContacts extends AsyncTask<Void, Void, String> 

3. Return auth2 from doInBackground :

  String auth2 = jsonObj.getString("auth");
return auth2;

4. Change onPostExecute parameter type from Void to String :

@Override
protected void onPostExecute(String auth2) {
super.onPostExecute(auth2);
//...
Toast.makeText(getApplicationContext(),
"String retrived:" + auth2, Toast.LENGTH_SHORT).show();
}

How can i get a value returned by doInBackground() from AsyncTask class

I suggest to make all the download operations in one AsyncTask (downloading the JSON string and the icon).

You need to have a class to wrap the download results:

Wrapper class:

private class JSONMarkerObject {
double lat = 0.0;
double lng = 0.0;
String name = "";
String iconURL = "";
Bitmap iconBitmap = null;
}

Helper functions:

private ArrayList<JSONMarkerObject> parseJSON(String content) {

ArrayList<JSONMarkerObject> markers = new ArrayList<MainActivity.JSONMarkerObject>();
try {
JSONArray array = new JSONArray(content);
for (int i = 0; i < array.length(); i++) {
JSONObject Marker = array.getJSONObject(i);
JSONMarkerObject obj = new JSONMarkerObject();

obj.lat = Double.parseDouble(Marker.getString("latitude"));
obj.lng = Double.parseDouble(Marker.getString("longitude"));
obj.name = Marker.getString("title");
obj.iconURL = Marker.getString("icone");
obj.iconBitmap = downloadIcon(obj.iconURL);
markers.add(obj);
}

} catch (NumberFormatException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return markers;

}

private Bitmap downloadIcon(String iconURL) {
Bitmap bmImg = null;
try {
URL url = new URL(iconURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
bmImg = null;
}

return bmImg;
}

Download task:

public class MyTask extends AsyncTask<String, String, ArrayList<JSONMarkerObject>> {

@Override
protected void onPreExecute() {

}

@Override
protected ArrayList<JSONMarkerObject> doInBackground(String... params) {

String content = HttpManager.getData(params[0]);
ArrayList<JSONMarkerObject> markers = parseJSON(content);
return markers;
}

@Override
protected void onPostExecute(ArrayList<JSONMarkerObject> result) {

try {

for (int i = 0; i < result.size(); i++) {

JSONMarkerObject obj = result.get(i);

if (InArea(obj.lat, obj.lng)) {
mMap.addMarker(new MarkerOptions().position(new LatLng(obj.lat, obj.lng)).title(obj.name)
.icon(BitmapDescriptorFactory.fromBitmap(obj.iconBitmap)));

}
}

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

@Override
protected void onProgressUpdate(String... values) {
// updateDisplay(values[0]);
}

}

I see no need for downloading the text first in a single task, and then downloading the icons in another single task, because the markers will appear on the map when the icons are downloaded, so there is no problem in downloading everything in one shot.

Edit

The simplest way to add an info window is to set the title() and
snippet() methods of the corresponding marker.

mMap.addMarker(new MarkerOptions()
.position(new LatLng(obj.lat, obj.lng))
.title(obj.name)
.icon(BitmapDescriptorFactory.fromBitmap(obj.iconBitmap)))
.setTitle(obj.name)
.snippet(obj.name);


Related Topics



Leave a reply



Submit