2012-05-26 11 views
17

Ich lerne gerade über AsyncTask und möchte es als separate Klasse verwenden, anstatt eine Unterklasse.Android, kann ich AsyncTask in einer separaten Klasse platzieren und einen Rückruf haben?

Zum Beispiel

class inetloader extends AsyncTask<String, Void, String> { 


    @Override 
    protected String doInBackground(String... urls) { 

     String response = ""; 

      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(urls[0]); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       InputStream content = execute.getEntity().getContent(); 

       BufferedReader buffer = new BufferedReader(
         new InputStreamReader(content)); 
       String s = ""; 
       while ((s = buffer.readLine()) != null) { 
        response += s; 
       } 

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

     return response; 
    } 


    @Override 
    protected void onPostExecute(String result) { 
     Log.e("xx",result); 
     // how do I pass this result back to the thread, that created me? 
    } 


} 

und die Haupt (ui) thread:

inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 
//il.onResult() 
//{ 
    ///do something... 
//} 

Dank!

+1

Ja, Sie können es in eine separate Klasse legen, aber die meisten Leute nicht, weil es Sinn macht Das ist normalerweise viel klarer, wenn es eine innere Klasse ist. Wenn du es in vielen Aktivitäten wiederverwenden willst, mach weiter. – keyser

+0

Ich plane es für verschiedene Zwecke zu verwenden, wie wenn ich es von hier aus rufe, auf Ergebnis sollte es das tun und das, wenn ich es von dort aus rufe, sollte es etwas anderes machen ... dafür wenn ich es behalte in der gleichen Klasse und habe es eine Funktion von dieser Klasse auf Ergebnis aufrufen, ich muss eine neue AsyncTask für jede Art von Aktion, die es zu tun haben muss machen ... –

+0

Benutzeroberfläche verwenden, implementieren Sie einfach Ihre Aktivität über eine Schnittstelle und in onPostExcute() der Asyn-Klasse mContext.implementedMethod() aufrufen. –

Antwort

32

Verwenden Sie eine Schnittstelle. Etwas wie:

interface CallBackListener{ 
    public void callback(); 
} 

Dann haben Sie dies in Ihrem UI-Thread:

inetloader il = new inetloader(); 
li.setListener(this); 
il.execute("http://www.google.com"); 

In inetloader hinzu:

CallBackListener mListener; 

    public void setListener(CallBackListener listener){ 
    mListener = listener; 
    } 

dann in PostExecute() tun:

mListener.callback(); 
+0

Danke, klingt wie es ist die richtige Richtung zu gehen. Vor allem, wenn ich einen CallBackListener mit dem inetloader erstellen könnte il = new inetloader(); und gib es in das il-Objekt. –

+0

Hmm ... seltsam, ich habe keinen "CallBackListener" in Android v3, vielleicht geht es um einen anderen Namen? –

+3

@RogerTravis Ja, Sie müssen eine CallBackListener-Schnittstelle selbst erstellen.Und vergiss nicht "implements CallBackLisnter" für deine Hauptbenutzeroberflächenklasse hinzuzufügen. –

1
inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 

String result = il.get();//put it in try-catch 
       ^^^^^^^^ 

here you get result which is in onPostExecute(String result)

+0

Nicht wirklich :(Ich brauche eine Art von OnResult-Listener, der ausgelöst wird, sobald die AsyncTask abgeschlossen ist, da die Abfrage einiger Server eine Weile dauern kann. Andererseits wird il.get() in eine While-Schleife (true) gesetzt klingt vielleicht zu primitiv, oder? :) Gibt es bessere Optionen? –

+2

@Samir: Das ist eine wirklich schlechte Idee. Obwohl es das Abrufen eines Ergebnisses aus der AsyncTask erlaubt, blockiert die Verwendung der 'get()' - Methode den UI-Thread und wandelt effektiv die asynchrone Prozedur in eine synchrone Prozedur um. Die einzige gültige Verwendung für die Methode 'get()', die ich jemals entwickelt habe, wäre die Verkettung zweier 'AsyncTasks'. – Squonk

3

können Sie die Aktivitätsinstanz übergeben Konstruktor und Aktivitätsfunktion rufen von dort ...
Wie Verwendung Schnittstelle:

public interface ResultUpdatable { 

    public void setResult(Object obj); 
    } 

dies in der Aktivität implementieren und übergeben der Konstruktor der Async-Aufgabe und aktualisieren Sie das Ergebnis von onPostExecute mit setResult Funktion.

Verwandte Themen