2012-05-26 14 views
17

Estoy aprendiendo acerca de AsyncTask y quiero usarlo como una clase separada, en lugar de una subclase.Android, ¿puedo poner AsyncTask en una clase separada y tener una devolución de llamada?

Por ejemplo,

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


} 

y la principal (UI) de rosca:

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

Gracias!

+1

Sí, puede ponerlo en una clase separada, pero la mayoría de las personas no lo hacen porque es purpo por lo general, es mucho más claro si se trata de una clase interna. Si vas a reutilizarlo en muchas actividades, adelante. – keyser

+0

Planeo usarlo para diferentes propósitos, como si lo llamo desde aquí, en el resultado debería hacer eso y eso, si lo llamo desde allí, en el resultado debería hacer algo más ... por lo tanto, si lo voy a mantener en la misma clase y hacer que invoque una función de esa clase en el resultado, tendré que hacer una nueva AsyncTask para cada tipo de acción que tenga que hacer en virtud de ... –

+0

usar interfaz, simplemente implemente su actividad mediante una interfaz y en onPostExcute() de la clase Asyn llame a mContext.implementedMethod(). –

Respuesta

32

Use una interfaz. Algo así como:

interface CallBackListener{ 
    public void callback(); 
} 

luego hacer esto en su hilo de interfaz de usuario:

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

En inetloader, añadir:

CallBackListener mListener; 

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

Luego, en postExecute(), hacer:

mListener.callback(); 
+0

Gracias, parece que es la dirección correcta para ir. Especialmente si pudiera crear un CallBackListener con el inetloader il = new inetloader(); y pasarlo al objeto il. –

+0

Hmm ... extraño, no tengo un "CallBackListener" en android v3, ¿puede que tenga algún otro nombre? –

+3

@RogerTravis Sí, tiene que crear una interfaz CallBackListener usted mismo.Y no olvide agregar "implementa CallBackLisnter" para su clase principal de IU. –

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

No realmente :(Necesito algún tipo de oyente onResult, que se activará una vez que la AsyncTask finalice, porque consultar algunos servidores puede llevar un tiempo. Por otro lado, poner il.get() en un ciclo while (true) puede parecer demasiado primitivo, ¿no? :) ¿hay mejores opciones? –

+2

@Samir: esta es una muy mala idea. Si bien permite recuperar un resultado de 'AsyncTask', usar el método' get() 'bloqueará el subproceso de la interfaz de usuario y convertirá efectivamente lo que debería ser un procedimiento asíncrono en uno síncrono. El único uso válido para el método 'get()' que alguna vez se me ocurrió fue para 'encadenar' dos 'AsyncTasks'. – Squonk

3

puede pasar a la instancia de actividad constructora y llamar a la función de la actividad a partir de ahí ...
Como interfaz de uso:

public interface ResultUpdatable { 

    public void setResult(Object obj); 
    } 

implementar esto en la actividad y pase el constructor de la tarea Async y actualiza el resultado desde onPostExecute usando la función setResult.

Cuestiones relacionadas