Return Data from Asynctask Class

how to return data from AsyncTask to main thread

to get result back in Main Thread you will need to use AsyncTask.get() method which make UI thread wait until execution of doInBackground is not completed but get() method call freeze the Main UI thread until doInBackground computation is not complete . start your AsyncTask using get() method as :

String str_result=new 
JSONfunctions().execute("http://192.168.6.43/employees.php").get();

move this line inside a Thread to avoid freezing of UI thread



Second and right way to utilize the use of AsyncTask move your code which you want to update with the result of doInBackground computation inside onPostExecute as :

public class JSONfunctions extends 
AsyncTask<String, Void, JSONObject> {

public Asynchtask delegate=null;

InputStream is;
String result ;
JSONObject jArray;

@Override
protected JSONObject doInBackground(String... params) {
// your code here....
return jArray;
//convert response to string

}
@Override
protected void onPostExecute(JSONObject result)
{
JSONArray employees =
result.getJSONArray("Employees");
// your code here...
ListAdapter adapter = new SimpleAdapter(MainActivity.this, mylist ,
R.layout.activity_main,
new String[] { "name", "email id","phone no" },
new int[] { R.id.item_title, R.id.item_emailid
,R.id.item_phoneno});
MainActivity.this.setListAdapter(adapter);

final ListView lv = MainActivity.this.getListView();
//....
}
}

Return data from AsyncTask class

The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.

public class URLWithParams {

public String url;
public List<NameValuePair> nameValuePairs;

public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}

and then I send it to a JSONClient:

public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";

ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}

@Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}

public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();

if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}

if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}

// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;

} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;
}

@Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}

public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}

}

Then call it from my main class like this

public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();

private String catalog_url = "URL";

private void getCatalogFromServer() {

URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;

try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void onRemoteCallComplete(String jsonBookCatalogList) {

Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");

if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;

DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}

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

}

}

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 retrieve the data from AsyncTasks doInBackground()?

The only way to do this is using a CallBack. You can do something like this:

new CallServiceTask(this).execute(request, url);

Then in your CallServiceTask add a local class variable and call a method from that class in your onPostExecute:

private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{
RestClient caller;

CallServiceTask(RestClient caller) {
this.caller = caller;
}

protected Object[] doInBackground(Object... params)
{
HttpUriRequest req = (HttpUriRequest) params[0];
String url = (String) params[1];
return executeRequest(req, url);
}

protected onPostExecute(Object result) {
caller.onBackgroundTaskCompleted(result);
}
}

Then simply use the Object as you like in the onBackgroundTaskCompleted() method in your RestClient class.

A more elegant and extendible solution would be to use interfaces. For an example implementation see this library. I've just started it but it has an example of what you want.

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.

Return data from AsyncTask Android

postExecute() can't return a value because who or what would it return to? Your original method that invoked the AsyncTask is gone because your AsyncTask is running in the background. It's asynchronous meaning when AsyncTask.execute() returns it's still running in the background, and hence postExecute() can't return a value because there's nothing to return it to.

Instead your AsyncTask needs a reference back to your Activity or some other object so it can post your values back to it. In your code the lines after you call execute() can't be there because your task hasn't finished. Instead you should create a method called updateSymbol( currentPrice, percentChange), move all that code below execute() in there, and in your AsyncTask you should pass a reference to the Activity. Then call updateSymbol( currentPrice, percentChange ) from the onPostExecute() method.

But, be careful if you have a reference back to an Activity it can be destroyed while your doInBackground() is running, and when postExecute() runs it should just drop the results or not attempt to update the UI. For example, the user rotates their phone causing the Activity to be destroyed. I find it best to hold a reference to the AsyncTask in the activity so it can cancel() it if the Activity is destroyed. You can call AsyncTask.cancel() then check if your task was canceled like:

public void postExecute( String result ) {
if( !isCanceled() ) {
// do your updating here
activity.setSymbol( result );
}
}

It's really easy to create a base class for all Activities so you can easily keep track of AsyncTasks running:

public class BaseActivity extends Activity {

List<AsyncTask> runningTasks;

public void onStop() {
for( AsyncTask task : runningTasks ) {
task.cancel(true);
}
}

public AsyncTask start( AsyncTask task ) {
runningTasks.add( task );
return task;
}

public void done( AsyncTask task ) {
runningTasks.remove( task );
}
}

Some quick pointers. You don't need execute( new String[] { "blah" + blah } ). Varargs in Java allow you to do this. execute( "blah" + blah ). You also are catching exceptions and continuing without really handling them. It will be hard when something really happens because your app catches them, and just continues as if nothing happened. If you get an error you might want to provide some feedback to the user and stop trying to execute that process. Stop, show an error to the user, and let them do the next thing. Move the catch blocks to the bottom of the methods.

How to get data from AsyncTask in android?

Just pass your ImageView to AsyncTask via constructor and then set image in onPostExecute like this:

ImageAsyncTask task = new ImageAsyncTask(myImageView);

private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView img;

ImageAsyncTask(Imageview img){
this.img = img;
}

...

protected void onPostExecute(Bitmap data) {
this.img.setImageBitmap(data);

}

How to fetch data out of AsyncTask class in android?

After doInBackground() your return will be forwarded to onPostExecute().

To use it in your activity refer this link : How to use Async result in UIThread



Related Topics



Leave a reply



Submit