Reputation: 4595
Hi and thanks for your help.
I have a method
that calls an AsyncTask
to retrieve some data from the net.
The method
is called several times in sequence and therefore launches several AsyncTasks.
From each launch of the method
I need to get back the correct result from the relative AsyncTask (and not from some other AsyncTask which was called before or after).
Any help very much appreciated.
EDIT EDIT EDIT EDIT Added rest of code.
Please Note: the whole process runs inside a Service.
public static class UpdateService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int[] appWidgetIds = intent.getIntArrayExtra("widgetsids");
final int N = appWidgetIds.length;
AppWidgetManager manager = AppWidgetManager.getInstance(this);
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.e("","i="+Integer.toString(i)+ " di "+Integer.toString(N));
RemoteViews view = buildUpdate(getApplicationContext(),
appWidgetIds);
manager.updateAppWidget(appWidgetId, view);
}
return (START_NOT_STICKY);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
private static RemoteViews buildUpdate(Context ctxt, int[] appWidgetIds) {
RemoteViews updateViews = new RemoteViews(ctxt.getPackageName(),
R.layout.widget);
updateViews.setTextViewText(R.id.price1, getPrice(list.get(0)
.getSymbol()));
}
//THIS METHOD IS CALLED SEVERAL TIMES IN SEQUENCE <----
private static String getPrice(String symbol) {
String result="";
UpdateTaskPrice up = new UpdateTaskPrice();
up.execute(symbol, null, null);
//HERE I WANT THE RESULT FROM onPostExecute() <----
return result;
}
//THIS IS THE ASYNCTASK WHICH IS LAUNCHED SEVERAL TIMES
public class UpdateTaskPrice extends AsyncTask<String, Void, String> {
@Override
protected void onProgressUpdate(Void... progress) {
}
@Override
protected void onPostExecute(String result) {
//HERE I RECEIVE THE RESULT FROM doInBackground <----
//I NEED TO PASS IT BACK TO getPrice() <----
}
@Override
protected String doInBackground(String... symbol) {
String result = "";
DefaultHttpClient client = new DefaultHttpClient();
String srt = "";
String url = context.getString(R.string.urlaternativo).concat(
symbol[0]);
HttpGet getMethod = new HttpGet(url);
try {
ResponseHandler<String> responseHandler = new BasicResponseHandler();
srt = client.execute(getMethod, responseHandler);
int inizio = srt.indexOf("<last data=\"");
int fine = srt.indexOf("\"/>", inizio + 12);
result = srt.substring(inizio + 12, fine);
} catch (Throwable t) {
// Log.e("ERROR", "ERROR", t);
}
//HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <----
return result;
}
}
Upvotes: 7
Views: 1477
Reputation: 7533
Well, I think you can pass the unique request id in the constructor of the AsyncTask
. Then in the postExecute()
method, update the UI with the result and the unique request id -
public class UpdateTaskPrice extends AsyncTask<String, Void, String> {
private int mIdentifier;
private Service mService;
public UpdateTaskPrice(Service service, int identifier) {
this.mIdentifier = identifier;
}
@Override
protected void onProgressUpdate(Void... progress) {
}
@Override
protected void onPostExecute(String result) {
((UpdateService) mService).informPrice(mIdentifier, result);
}
@Override
protected String doInBackground(String... symbol) {
String result = "";
DefaultHttpClient client = new DefaultHttpClient();
String srt = "";
String url = context.getString(R.string.urlaternativo).concat(
symbol[0]);
HttpGet getMethod = new HttpGet(url);
try {
ResponseHandler<String> responseHandler = new BasicResponseHandler();
srt = client.execute(getMethod, responseHandler);
int inizio = srt.indexOf("<last data=\"");
int fine = srt.indexOf("\"/>", inizio + 12);
result = srt.substring(inizio + 12, fine);
} catch (Throwable t) {
// Log.e("ERROR", "ERROR", t);
}
//HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <----
return result;
}
}
Upvotes: 0
Reputation: 4445
You can get the data from multiple asynctask, but the place you want the result is not possible with the asyctask, you need to use more encapsulation to structure this problem.
the problem with your structure is...
private static String getPrice(String symbol) {
String result="";
UpdateTaskPrice up = new UpdateTaskPrice();
up.execute(symbol, null, null);
//HERE I WANT THE RESULT FROM onPostExecute() <----
return result;
}
when you are starting the new thread it will first execute the statement which is return after task.execute(symbol); in your case it is return statement and then it will exucute pre.. doin.. and post...
Hear is the pattern which you can use to retrieve the data from multiple AsycTask
//Calling to the method callAsyncTask;
callAsyncTask(new AsyncResultCallback(){
public void onResult(String result, String symbol){
//TODO dosomthing with the result
}
});
public void callAsyncTask(AsyncResultCallback callback){
new UpdateTaskPrice(callback).execurte(symbol);
}
public interface AsyncResultCallback{
public void onResult(String result, String symbol);
}
public class UpdateTaskPrice extends AsyncTask<String, Void, String> {
AsyncResultCallback callback;
String symbol;
UpdateTaskPrice(AsyncResultCallback callback){
this.callback = callback;
}
@Override
protected void onProgressUpdate(Void... progress) {
}
@Override
protected void onPostExecute(String result) {
callback.onResult(result, symbol);
}
@Override
protected String doInBackground(String... symbol) {
this.symbol = symbol;
String result = "";
DefaultHttpClient client = new DefaultHttpClient();
String srt = "";
String url = context.getString(R.string.urlaternativo).concat(symbol[0]);
HttpGet getMethod = new HttpGet(url);
try {
ResponseHandler<String> responseHandler = new BasicResponseHandler();
srt = client.execute(getMethod, responseHandler);
int inizio = srt.indexOf("<last data=\"");
int fine = srt.indexOf("\"/>", inizio + 12);
result = srt.substring(inizio + 12, fine);
} catch (Throwable t) {
// Log.e("ERROR", "ERROR", t);
}
//HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <----
return result;
}
}
hope that help.
Upvotes: 0
Reputation: 1385
AsyncTask is asynchronous and run in a separate thread. So it is not possible to get the result of AsyncTask in very next statement after you execute it.
To get the relative results from AsyncTask, add a member variable "mRequestId" in your UpdateTaskPrice class and before calling UpdateTaskPrice.execute, set unique request ID.
in "onPostExecute" method of your UpdateTaskPrice class, you can return and process result using this Request Id.
public class UpdateTaskPrice extends AsyncTask<String, Void, String> {
protected int mRequestId;
public void setRequestId (int requestId)
{
this.mRequestId = requestId;
}
@Override
protected void onProgressUpdate(Void... progress) {
}
@Override
protected void onPostExecute(String result) {
// do whatever with result using mRequestId
}
@Override
protected String doInBackground(String... symbol) {
String result = "";
DefaultHttpClient client = new DefaultHttpClient();
String srt = "";
String url = context.getString(R.string.urlaternativo).concat(
symbol[0]);
HttpGet getMethod = new HttpGet(url);
try {
ResponseHandler<String> responseHandler = new BasicResponseHandler();
srt = client.execute(getMethod, responseHandler);
int inizio = srt.indexOf("<last data=\"");
int fine = srt.indexOf("\"/>", inizio + 12);
result = srt.substring(inizio + 12, fine);
} catch (Throwable t) {
// Log.e("ERROR", "ERROR", t);
}
//HERE I GET THE RESULT I WANT, AND PASS IT TO onPostExecute() <----
return result;
}
}
Upvotes: 10