2011-10-10 28 views
6

La mia applicazione recupera un codice html da Internet e, una volta terminato, lo visualizza sullo schermo dei dispositivi. Poiché ci vogliono circa 3-4 secondi per farlo, in questo momento lo schermo rimane nero, mi piacerebbe usare una finestra di dialogo di avanzamento. Questo è il mio codice:Finestra di dialogo di avanzamento di 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(); 

Il programma funziona ma non visualizza più nulla. Ho un errore in logcat:

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

Potrebbe aiutarmi per favore? Grazie in anticipo.

+0

Le date risposte sono corrette, ma mi piacerebbe aggiungere qualcosa. ProgressDialogs ha 2 stili: STYLE_SPINNER (predefinito) e STYLE_HORIZONTAL. Secondo [i dialoghi ui] (http://developer.android.com/guide/topics/ui/dialogs.html) dovremmo seguire le [linee guida di progettazione per Progress & Activity] (http://developer.android.com /design/building-blocks/progress.html) e utilizzare uno STYLE_HORIZONTAL (se pertinente e possibile). A tale proposito ho trovato [questo tutorial] (http://www.pavanh.com/2013/04/android-progress-dialog-example.html) molto utile. Ora hai la possibilità di scegliere quale stile di ProgressDialog vuoi ... –

risposta

17

L'errore è sufficientemente esplicativo. Per aggiornare un oggetto visivo è necessario eseguire le modifiche all'interno del thread principale. Una soluzione rapida e sporca potrebbe chiamare il codice di aggiornamento all'interno di runOnUiThread().

Tuttavia nel tuo caso utilizzerei uno AsyncTask per scaricare e aggiornare l'avanzamento della barra di avanzamento. Il compito ha la proprietà per l'esecuzione su thread UI quando finisce (in modo da poter aggiornare il punto di vista lì, come chiudere la finestra di corso)

Here è un esempio di come utilizzare un AsyncTask per visualizzare una finestra di avanzamento del download.

Aggiornamento

StackOverflow ha già le risposte a tutte le vostre domande. Here è un esempio di AsyncTask per scaricare alcuni contenuti e visualizzare l'avanzamento del download. Proprio quello che vuoi

Update 2

Ok qui è il codice utilizza 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

Potresti aiutarmi? Sono nuovo di Android e non ho compreso appieno quell'esempio. – Teo

+0

Dai un'occhiata all'aggiornamento –

+0

La cosa è .. Non voglio cambiare le mie funzioni perché il programma funziona bene, un po 'lento. Voglio mettere quelle funzioni in un thread in background e mentre quelle funzioni sono in esecuzione, voglio visualizzare la finestra di avanzamento. – Teo

1

Creare un thread dell'interfaccia utente dopo aver completato il funzionamento della rete

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

      } 
     }); 
4

Hai bisogno di fare in questo modo

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

e dove posso eliminare progressdialog? – Teo

+0

Suppongo che tu abbia appena fatto una funzione in quella scrittura sopra il codice e al posto del codice di scrittura del commento per chiudere la finestra di dialogo e chiamare il divertimento dal tuo task ogni volta che ne hai bisogno – MKJParekh

2

Congeda la tua finestra come questa:

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

Ho sostituito 'progressDialog.dismiss();' con il tuo codice. Ora il programma si blocca. – Teo

+0

metta questa riga Handler handler = new Handler(); fuori thread .... –

+0

Ho fatto questo, il programma si blocca .. firs dice: 'Impossibile creare il gestore all'interno del thread che non ha chiamato Looper.prepare()' e quindi 'String out of bound' – Teo

Problemi correlati