2010-08-02 22 views
17

Tengo una aplicación que está realizando solicitudes HTTP (específicamente llamando a la API de FogBugz) cuando el usuario hace clic en ciertos botones. En este momento, solo estoy creando un servicio cuando se inicia la aplicación, y luego llamo a diferentes métodos en ese servicio para completar las solicitudes. Sin embargo, cuando hago esto, suele haber un bloqueo en el hilo de UI. He examinado AsyncTask, pero no estoy seguro de que vaya a hacer lo que quiero lograr. Debido a que necesito analizar al instante el XML que devuelve la solicitud HTTP, necesito tener un proceso que pueda devolver estos datos al hilo de la interfaz de usuario. ¿Podrá ASyncTask lograr esto, o hay alguna otra manera?Cómo usar un hilo separado para realizar solicitudes HTTP

public static InputStream makeRequest(String httpRequest) 
    { 
     In a separate thread, run HTTP Request, get back and process, return inputstream 
    } 

Este método es llamado por varios otros para realizar HttpRequests. Una vez que se devuelve la ruta de entrada, los otros métodos analizan para obtener información específica.

Respuesta

59

La forma más sencilla de hacerlo sería más que hacer algo como

//Body of your click handler 
Thread thread = new Thread(new Runnable(){ 
    @Override 
    public void run(){ 
    //code to do the HTTP request 
    } 
}); 
thread.start(); 

Eso hará que el código dentro del método run() para ejecutar en un nuevo hilo de ejecución. Puede mirar una tarea asíncrona si lo desea, aunque yo personalmente nunca la haya usado. Esta es una forma rápida y sencilla de hacer las cosas.

Con respecto a la devolución de información, usaría un Handler object que efectivamente le permite configurar una cola de mensajes para un hilo determinado y pasarle mensajes que causan la ejecución de un código específico. La razón por la que necesita hacer esto es porque Android no permitirá que ningún hilo que no sea el hilo de la interfaz de usuario actualice la interfaz de usuario real.

¿Eso responde a su pregunta? Sé que mi primer pase no solucionó completamente todos sus problemas.

Editar Básicamente, lo que se hace es definir un objeto manejador en su Activity como

private Handler handler_ = new Handler(){ 
    @Override 
    public void handleMessage(Message msg){ 

    } 

}; 

También se crea int constantes estáticas que ayudan a contar el manejador de qué hacer. Básicamente, los usa para permitir que varios tipos diferentes de mensajes pasen a una instancia de un controlador. Si solo va a haber un mensaje que se remite, entonces no tiene que preocuparse por eso.

Por ejemplo

private static final int UPDATE_UI = 1; 

Para enviar un mensaje al controlador de llamar

handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance)); 

Desde el manejador:

private Handler handler_ = new Handler(){ 
    @Override 
public void handleMessage(Message msg){ 
    switch(msg.what){ 
      case UPDATE_UI: 
      InputStream is = (InputStream)msg.obj; 
      //do what you need to with the InputStream 
      break; 
     } 
    } 

}; 

Alternativamente, cuando se añade el inputStreamInstance a la Message objeto, puede pasar cualquier objeto que desee, así que si desea analizarlo en a algún tipo de objeto contenedor o algo así, podrías hacer eso también. Simplemente devuélvelo a ese objeto desde el controlador.

+0

Gracias por la ayuda. Todavía tengo problemas para enviar y recibir información del hilo por separado. Actualicé mi pregunta para aclarar lo que tengo que hacer. Con respecto al objeto Handler, lo usaría en el hilo secundario, para pasar información, por ejemplo, el flujo de entrada? – mbauer14

4

Intente utilizar AsyncTask.Ir a este Link para más:

private class SyncIncoData extends AsyncTask<String, String, String> { 
    ProgressBar pb; 
    ProgressBar pbar; 

    @Override 
    protected String doInBackground(String... urls) { 
     for (int i = 0; i <= 100; i++) { 
      publishProgress(i); 
     } 
     return null; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 

     pb = (ProgressBar) findViewById(R.id.progressBarsync4); 
     pb.setVisibility(View.VISIBLE); 

    } 

    @Override 
    protected void onPostExecute(String result) { 

     pb = (ProgressBar) findViewById(R.id.progressBarsync4); 
     pb.setVisibility(View.INVISIBLE); 

    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     pbar = (ProgressBar) findViewById(R.id.progressBarpbar); 
     pbar.setProgress(Integer.parseInt(values[0])); 
     super.onProgressUpdate(values); 
    } 
} 

Escribir el programa para la petición http dentro doinbackgroud()

Cuestiones relacionadas