2016-11-04 3 views
0

Ich sah viele Fragen über Ergebnisse von Async-Aufgabe, aber keine von ihnen löste mein Problem. Die Sache, die ich tun möchte, ist von asynchronen Aufgaben Array von MyClass-Objekten zu bekommen und sie in der Benutzeroberfläche zu verwenden, aber in verschiedenen Situationen habe ich verschiedene UI. Manchmal fülle ich recyclerview mit meinem Array, manchmal fülle ich endlose Tabbed-Aktivitäten mit meinem Array. Das bedeutet, dass ich mein UI-Element nicht an die Async-Aufgabe übergeben kann, um es in onPostExecute() zu behandeln. Das Ergebnis, das ich von einer Async-Aufgabe erhalten möchte, ist genau ein Array von MyClass-Objekten, die dann in verschiedenen Situationen auf unterschiedliche Weise damit arbeiten. Und auch eine wichtige Sache ist, dass ich erst nach AsyncTask ausführt meinen UI füllen sollte (denn wenn es nach wie vor ist die Ausführung ich keine Daten UI mit füllen), so kann ich nicht einfach etwas schreiben wieErgebnis von asynctask erhalten und es behandeln

MyClass[] result = new MyAsyncTask().execute().getResult() 
MyUI.fillWith(result) 

, weil die meist wahrscheinlich werde ich NPE bekommen.

Also wie kann ich mein Ergebnis als Array von MyClass-Objekten zurück und fülle meine UI damit erst nachdem ich das Ergebnis bekomme (So in UI-Thread sollte ich Informationen bekommen, dass meine asynctask die ganze Arbeit gemacht hat und erst danach I kann die Benutzeroberfläche mit meinen Daten füllen. Und natürlich möchte ich meinen UI-Thread nicht blockieren)?

Handling UI in onPostExecute() wird mein Problem nicht lösen, aus Gründen, die ich früher schrieb. Die Abdeckung von AsyncTask mit der Schnittstelle scheint auch nicht etwas zu sein, das ich brauche. Und ich habe eine Lösung mit einem eindeutigen Token für AsyncTask gesehen, aber ich habe nicht verstanden, wie das funktioniert.

+0

Aber Sie haben die UI-Thread in OnPostExecute zu handhaben, weil das einfach ist, wie es funktioniert. Vielleicht sollten Sie AsyncTask jedoch nicht verwenden. Haben Sie andere Netzwerkbibliotheken in Betracht gezogen? –

+1

Diese Top-Antwort ist im Wesentlichen, was Sie suchen, ersetzen Sie einfach "String output" in der Antwort-Schnittstelle mit 'MyClass [] output', und Sie sollten –

+0

@ cricket_007 eingestellt werden Ja, das ist, was ich brauchte, danke. Aber das scheint eine komplizierte Lösung zu sein. Das ist seltsam, denn ich verstehe, dass dies ein häufiges Problem ist. – Leopik

Antwort

3

Rather UI-Element direkt an die AsyncTask als vorbei, schafft eine Schnittstelle, die die Maßnahmen zu ergreifen, sobald die Aufgabe erledigt ist:

public interface MyTaskHandler { 
    void onComplete(MyClass[] results); 
} 

Und Ihre Aufgabe, diese Schnittstelle machen akzeptieren und nennt es in onPostExecute:

(in der realen Implementierung müssen Sie WeakReferences verwenden oder die Referenz aufheben, wenn Ihre Aktivität zerstört wird, genau wie Sie es mit Sichten tun würden, da Ihr Handler einen Verweis auf einige generiert Ansicht)

Dann können Sie verschiedene Implementierungen von MyTaskHandler Pass auf, was Sie tun möchten:

public class MyActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    new MyAsyncTask(new MyTaskHandler() { 
     @Override 
     public void onComplete(MyClass[] results) { 
     // load into list view 
     } 
    }).execute(); 

    new MyAsyncTask(new MyTaskHandler() { 
     @Override 
     public void onComplete(MyClass[] results) { 
     // load into tabs 
     } 
    }).execute(); 
    } 
} 
Verwandte Themen