2012-06-29 18 views
23

Estoy tratando de mostrar un diálogo de progreso durante el método onCreate() de una de mis actividades, hacer el trabajo para llenar la pantalla hecha en un hilo y luego cerrar el diálogo de progreso.Android runOnUiThread explicación

Aquí es mi onCreateMethod()

dialog = new ProgressDialog(HeadlineBoard.this); 
     dialog.setMessage("Populating Headlines....."); 
     dialog.show(); 
     populateTable(); 

El método populateTable contiene mi hilo y el código para cerrar el diálogo, pero por alguna razón. La actividad aparece en blanco durante aproximadamente 10 segundos (haciendo el trabajo populateTable()), y luego veo la pantalla. Nunca veo el diálogo mostrado, ninguna idea?

Aquí está el populateTable() Código:

//Adds a row to the table for each headline passed in 
private void populateTable() { 
    new Thread() { 
     @Override 
     public void run() { 
      //If there are stories, add them to the table 
      for (Parcelable currentHeadline : allHeadlines) { 
       addHeadlineToTable(currentHeadline); 
      } 
       try { 
        // code runs in a thread 
        runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           dialog.dismiss(); 
          } 
        }); 
       } catch (final Exception ex) { 
        Log.i("---","Exception in thread"); 
       } 
     } 
}.start(); 

} 
+1

'Si hay historias, agrégalas a la tabla'. Ejecuta este código en el hilo de UI, no en el hilo que ha creado. –

+0

no estoy seguro de lo que está sugiriendo? – user1154644

+0

Mover todo el código en runOnUiThread out para anular run(), solo deje 'dialog.dismiss();' –

Respuesta

26

Si ya tiene los datos "para (parcelable currentHeadline: allHeadlines)," ¿por qué haces eso en un hilo separado?

Usted debe pedir los datos en un hilo separado, y cuando se termine la recolección, entonces llame a su método de populateTables en el hilo de interfaz de usuario:

private void populateTable() { 
    runOnUiThread(new Runnable(){ 
     public void run() { 
      //If there are stories, add them to the table 
      for (Parcelable currentHeadline : allHeadlines) { 
       addHeadlineToTable(currentHeadline); 
      } 
      try { 
       dialog.dismiss(); 
      } catch (final Exception ex) { 
       Log.i("---","Exception in thread"); 
      } 
     } 
    }); 
} 
+0

Intenté esto, funciona sin lanzar una excepción, pero todavía nunca ve el diálogo, simplemente se queda en blanco y luego muestra la actividad una vez que se ha construido la pantalla. – user1154644

+0

Entonces estás haciendo algo diferente. ¿Estás creando el diálogo en el subproceso UI? ¿Y por qué estás usando HeadLineBoard.this? ¿Por qué no tu contexto? – Guardanis

+0

no, el diálogo se crea en onCreate() para la actividad. – user1154644

5

Esto debería funcionar para usted

public class MyActivity extends Activity { 

    protected ProgressDialog mProgressDialog; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     populateTable(); 
    } 

    private void populateTable() { 
     mProgressDialog = ProgressDialog.show(this, "Please wait","Long operation starts...", true); 
     new Thread() { 
      @Override 
      public void run() { 

       doLongOperation(); 
       try { 

        // code runs in a thread 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          mProgressDialog.dismiss(); 
         } 
        }); 
       } catch (final Exception ex) { 
        Log.i("---","Exception in thread"); 
       } 
      } 
     }.start(); 

    } 

    /** fake operation for testing purpose */ 
    protected void doLongOperation() { 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
     } 

    } 
} 
+0

mmm .. todavía está recibiendo el problema de la ventana filtrada. – user1154644

+0

en su solución intente agregar Thread.sleep (500) antes del bucle for y vea lo que obtiene !!, –

+0

mismo comportamiento. Tengo la inicialización de ProgressDialog y show() en el método onCreate() para la actividad, si eso es importante. – user1154644

2

En lugar de crear un hilo y usar runOnUIThread, este es un trabajo perfecto para ASyncTask:

  • En onPreExecute, cree & para mostrar el cuadro de diálogo.

  • en doInBackgroundpreparar los datos, pero no toque la interfaz de usuario - almacenar cada dato preparado en un campo, a continuación, llamar publishProgress.

  • En onProgressUpdate lea el campo de referencia & haga el cambio/adición apropiado a la interfaz de usuario.

  • En onPostExecute desactive el cuadro de diálogo.


Si usted tiene otras razones para querer un hilo, o está añadiendo la lógica de IU-tocar a un tema existente, y luego hacer una técnica similar a lo que describo, para ejecutarlo en hilo de interfaz de usuario sólo para breve períodos, usando runOnUIThread para cada paso de UI. En este caso, almacenará cada dato en una variable local final (o en un campo de su clase), y luego lo usará dentro de un bloque runOnUIThread.

+0

¡Ayudó mucho! Más en http://developer.android.com/reference/android/os/AsyncTask.html – naren