2011-10-10 16 views
6

Mi aplicación obtiene algún código html de Internet y cuando termina, lo muestra en la pantalla de dispositivos. Dado que demora entre 3 y 4 segundos en hacerlo, en este momento en que la pantalla permanece en negro, me gustaría utilizar un cuadro de diálogo de progreso. Este es mi código:Diálogo de progreso de Android

package com.nextlogic.golfnews; 



// ALL THE IMPORTS .... 

public class Activity1 extends Activity { 

    private ProgressDialog progressDialog; 
@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main2); 

     progressDialog = ProgressDialog.show(Activity1.this, "", "Loading..."); 
     new Thread() 
     { 
      public void run() 
      { 

      try 
       { 
       sleep(2000); 

      // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME 
} 
    catch (Exception e) 
    { 
     Log.e("tag",e.getMessage()); 
    } 
// dismiss the progressdialog 
    progressDialog.dismiss(); 
} 
}.start(); 

El programa funciona pero ya no muestra nada. Tengo un error en logcat:

Only the original thread that created a view hierarchy can touch its views. 

¿Podría ayudarme? Gracias por adelantado.

+0

Las respuestas dadas son correctas, pero me gustaría agregar algo. ProgressDialogs tiene 2 estilos: STYLE_SPINNER (predeterminado) y STYLE_HORIZONTAL. De acuerdo con los [ui diálogos] (http://developer.android.com/guide/topics/ui/dialogs.html) debemos seguir las [pautas de diseño para Progreso y Actividad] (http://developer.android.com /design/building-blocks/progress.html) y usa un STYLE_HORIZONTAL (si es relevante y posible). Sobre este asunto encontré [este tutorial] (http://www.pavanh.com/2013/04/android-progress-dialog-example.html) muy útil. Ahora tiene la opción del estilo de ProgressDialog que desea ... –

Respuesta

17

El error es suficientemente explicativo. Para actualizar un objeto visual, debe ejecutar los cambios dentro del hilo principal. Una solución rápida y sucia podría estar llamando al código de actualización dentro de runOnUiThread().

Sin embargo, en su caso utilizaría un AsyncTask para descargar y actualizar el progreso de la barra de progreso. La tarea tiene la propiedad de ejecutarse en el subproceso de la interfaz de usuario cuando finaliza (para poder actualizar las vistas allí, como ignorar el cuadro de diálogo de progreso)

Here es un ejemplo de cómo usar una AsyncTask para mostrar un diálogo de progreso de descarga.

actualización

Stackoverflow ya tiene las respuestas a todas sus preguntas. Here es un ejemplo de AsyncTask para descargar algunos contenidos y mostrar el progreso de la descarga. Justo lo que quieres

Actualización 2

Ok aquí está el código utilizando un AsyncTask:

public class Activity1 extends Activity 
{ 
    private ProgressDialog progressDialog; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     new AsyncTask<Integer, Integer, Boolean>() 
     { 
      ProgressDialog progressDialog; 

      @Override 
      protected void onPreExecute() 
      { 
       /* 
       * This is executed on UI thread before doInBackground(). It is 
       * the perfect place to show the progress dialog. 
       */ 
       progressDialog = ProgressDialog.show(Activity1.this, "", 
         "Loading..."); 
      } 

      @Override 
      protected Boolean doInBackground(Integer... params) 
      { 
       if (params == null) 
       { 
        return false; 
       } 
       try 
       { 
        /* 
        * This is run on a background thread, so we can sleep here 
        * or do whatever we want without blocking UI thread. A more 
        * advanced use would download chunks of fixed size and call 
        * publishProgress(); 
        */ 
        Thread.sleep(params[0]); 
        // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME 
       } 
       catch (Exception e) 
       { 
        Log.e("tag", e.getMessage()); 
        /* 
        * The task failed 
        */ 
        return false; 
       } 

       /* 
       * The task succeeded 
       */ 
       return true; 
      } 

      @Override 
      protected void onPostExecute(Boolean result) 
      { 
       progressDialog.dismiss(); 
       /* 
       * Update here your view objects with content from download. It 
       * is save to dismiss dialogs, update views, etc., since we are 
       * working on UI thread. 
       */ 
       AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this); 
       b.setTitle(android.R.string.dialog_alert_title); 
       if (result) 
       { 
        b.setMessage("Download succeeded"); 
       } 
       else 
       { 
        b.setMessage("Download failed"); 
       } 
       b.setPositiveButton(getString(android.R.string.ok), 
         new DialogInterface.OnClickListener() 
         { 

          @Override 
          public void onClick(DialogInterface dlg, int arg1) 
          { 
           dlg.dismiss(); 
          } 
         }); 
       b.create().show(); 
      } 
     }.execute(2000); 

     new Thread() 
     { 
      @Override 
      public void run() 
      { 

       // dismiss the progressdialog 
       progressDialog.dismiss(); 
      } 
     }.start(); 
    } 
} 
+0

¿Podría ayudarme? Soy nuevo en Android y no entendí completamente ese ejemplo. – Teo

+0

Eche un vistazo a la actualización –

+0

La cosa es ... No quiero cambiar mis funciones porque el programa funciona bien, un poco lento. Quiero poner esas funciones en un hilo de fondo y mientras esas funciones se están ejecutando, quiero mostrar el cuadro de diálogo de progreso. – Teo

1

crear un hilo de interfaz de usuario después de completar la operación de red

runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
      progressDialog.dismiss(); 

      } 
     }); 
4

Es necesario hacer esta manera

runOnUiThread(new Runnable() { 
    public void run() { 
     // Do Your Stuff 
    }}); 
+0

y ¿dónde descarto el progresoDialog? – Teo

+0

supongo que solo hace una función en ese código escrito arriba y en lugar de escribir código de comentario para descartar el diálogo y llamar a la diversión de su tarea cada vez que necesite – MKJParekh

2

desestimar su diálogo como este:

Handler handler = new Handler(); 
handler.post(new Runnable(){ 
    public void run(){ 
     progressDialog.dismiss(); 
    } 
}); 
+0

He reemplazado 'progressDialog.dismiss();' con su código. Ahora el programa se cuelga. – Teo

+0

poner esta línea Handler handler = new Handler(); fuera de hilo .... –

+0

Hice esto, el programa se cuelga ... primero dice: 'No se puede crear el controlador dentro de un hilo que no ha llamado a Looper.prepare()' y luego 'String out of bounds' – Teo

Cuestiones relacionadas