2013-03-25 14 views
7

Hallo und vielen Dank für Ihre Hilfe.Ergebnisse von mehreren AsyncTasks erhalten

Ich habe eine method, die eine AsyncTask ruft, um einige Daten aus dem Netz abzurufen.

Die methodwird mehrmals nacheinander aufgerufen und startet daher mehrere AsyncTasks.

Von jedem Start der method muss ich das richtige Ergebnis von der relativen AsyncTask (und nicht von einer anderen AsyncTask, die vor oder nach aufgerufen wurde) zurück erhalten.

Jede Hilfe sehr geschätzt.


EDIT EDIT EDIT EDIT Hinzugefügt Rest des Codes.

Bitte beachten Sie: Der gesamte Prozess läuft in einem 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; 
    } 
} 
+1

Es ist machbar, aber nicht empfohlen über 'Asynctask.get()', ich habe diese spezielle API ein wenig mehr in [diese Antwort] erklärt (http://stackoverflow.com/questions/8921244/return-data-from -asynctask-android/8922074 # 8922074). – yorkw

+0

Warum geben Sie die RemoteViews nicht einfach an Ihre AsyncTask UpdateTaskPrice in ihrem Konstruktor und 'setTextViewText' in die onPostExecute? Auf diese Weise weiß jede AsyncTask, welche View aktualisiert werden soll, und Sie benötigen nicht einmal das Ergebnis –

+0

einen Intentservice. das ist synchron genug. – njzk2

Antwort

10

AsyncTask ist asynchron und wird in einem separaten Thread ausgeführt. Daher ist es nicht möglich, das Ergebnis von AsyncTask in der nächsten Anweisung zu erhalten, nachdem Sie es ausgeführt haben.

Um die relativen Ergebnisse von AsyncTask abzurufen, fügen Sie in Ihrer UpdateTaskPrice-Klasse eine Mitgliedsvariable "mRequestId" hinzu und legen Sie vor dem Aufruf von UpdateTaskPrice.execute die eindeutige Anforderungs-ID fest.

In der "onPostExecute" -Methode Ihrer UpdateTaskPrice-Klasse können Sie Ergebnisse mit dieser Anforderungs-ID zurückgeben und verarbeiten.

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

Vielen Dank! Ich vermutete, dass ich so etwas tun musste. Bitte, ich bitte Sie höflich, wenn Sie die Antwort etwas genauer erläutern könnten, da ich mir nicht ganz sicher bin, wie ich das Ergebnis und die RequestId an die 'getPrice' Methode weitergeben kann. Danke noch einmal! –

+1

AsyncTasks sollen im Hintergrund ausgeführt werden. Um die von der getPrice-Methode zurückgegebenen Ergebnisse anzuzeigen, müssen Sie die Ansicht Ihrer Aktivität aktualisieren. onPostExecute-Methode wird im Hauptthread von Activity ausgeführt. Wenn Sie den Verweis Ihrer Aktivität in UpdateTaskPrice übergeben (wie mRequestId), können Sie auf die Ansicht von Activity in der Methode onPostExecute zugreifen. Sie können auch eine andere Methode Ihrer Aktivität aufrufen, die für das Parsen des Ergebnisses verantwortlich ist und den vom Ergebnis geparsten Preis anzeigt – Amit

+0

Danke. Ich bekomme es und ich verstehe es nicht ... Bitte Amit wäre Sie so nett mir zu zeigen, wie ich den Code ändern soll? Vielen Dank! –

0

Nun, ich glaube, Sie die einzigartige Anforderungs-ID im Konstruktor des AsyncTask passieren kann. Dann in der postExecute() Methode, aktualisieren Sie die Benutzeroberfläche mit dem Ergebnis und die einmalige Anfrage 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; 
    } 
} 
0

Sie können die Daten aus mehreren AsyncTask, aber der Ort, den Sie das Ergebnis wollen, ist nicht möglich mit dem asyctask, Sie müssen mehr Einkapselung verwenden, um dieses Problem zu strukturieren.

das Problem mit der Struktur ist ...

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

, wenn Sie den neuen Thread beginnen, wird zunächst die Anweisung auszuführen, die Rückkehr nach task.execute ist (Symbol); in Ihrem Fall ist es return-Anweisung und dann wird es exucute pre .. doin .. und Post ...

Hear das Muster, das Sie die Daten aus mehreren AsycTask können

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

abrufen hoffe, dass Hilfe.

Verwandte Themen