2011-06-02 19 views
5

Estoy tratando de usar un AsyncTask para descargar un archivo con un progreso de notificación. Todo funciona bien (descargas en el hilo de fondo), excepto que cada vez que agrego el código para actualizar la barra de progreso a través del publishProgress(), se congela todo el teléfono, hasta que la descarga finalice y la notificación muestre "Descarga completada".Congelación de subprocesos de UI con AsyncTask

Estoy completamente perdido en cuanto a por qué este es el caso, pero quizás estoy pensando que es a lo largo de las líneas del publishProgress((downloadedSize/totalSize) * 100) que estoy usando?

De todas formas aquí es el DownloadDataTask:

protected String doInBackground(RomDataSet... params) { 
     try { 

      // Download file here, all good 

      //now, read through the input buffer and write the contents to the file 
      while ((bufferLength = inputStream.read(buffer)) > 0) { 
       //add the data in the buffer to the file in the file output stream (the file on the sd card 
       fileOutput.write(buffer, 0, bufferLength); 
       //add up the size so we know how much is downloaded 
       downloadedSize += bufferLength; 
       //this is where you would do something to report the prgress, like this maybe 

       publishProgress((downloadedSize/totalSize) * 100); 
      } 
      //close the output stream when done 
      fileOutput.close(); 

     //catch some possible errors... 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPreExecute() { 
     Intent intent = new Intent(ListActivity.this, ListActivity.class); 
     pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); 

     // configure the notification 
     notification = new Notification(R.drawable.ic_stat_rom, "Downloading Rom via RomGet", System 
       .currentTimeMillis()); 
     notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; 
     notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.layout_download); 
     notification.contentIntent = pendingIntent; 
     notification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon_rom); 
     notification.contentView.setTextViewText(R.id.download_description, "Downloading"); 
     notification.contentView.setProgressBar(R.id.download_progress, 100, 0, false); 

     getApplicationContext(); 
     notificationManager = (NotificationManager) getApplicationContext().getSystemService(
       Context.NOTIFICATION_SERVICE); 

     notificationManager.notify(43, notification); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... progress) { 
     //notification.contentView.setProgressBar(R.id.download_progress, 100, Math.round(progress[0]), false); 
     notification.contentView.setTextViewText(R.id.download_description, Integer.toString(progress[0])); 
     // inform the progress bar of updates in progress 
     notificationManager.notify(43, notification); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     notification.contentView.setProgressBar(R.id.download_progress, 100, 100, false); 
     notification.contentView.setTextViewText(R.id.download_description, "Done"); 
     notificationManager.notify(43, notification); 
    } 

estoy realmente atascado en este caso - Cualquier ayuda sería apreciada. Cheers

@Override 
    protected void onProgressUpdate(Integer... progress) { 
     if ((progress[0] - lastSize) > 5000) { 
      lastSize = progress[0]; 
      notification.contentView.setProgressBar(R.id.download_progress, totalSize, progress[0], false); 
      //notification.contentView.setTextViewText(R.id.download_description, Integer.toString(progress[0])); 
      // inform the progress bar of updates in progress 
      notificationManager.notify(43, notification); 
     } 
    } 
+0

Tal vez está llamando 'publishProgress()' con demasiada frecuencia? ¿Qué tal si guardamos el último valor de '(downloadSize/totalSize) * 100' en un entero y solo llamamos a' publishProgress() 'cuando es diferente del valor anterior? – dmon

+0

Excelente idea, excepto que ahora no se congela, pero me da el siguiente error (lo he editado en la publicación principal) – jsw

+0

Definitivamente debe incluir el resto del código. No hay forma de que podamos decir por qué es nulo y por qué sin él. Todo lo que necesita hacer para resolver esto es seguir cuidadosamente el seguimiento de la pila y tomar notas de lo que está sucediendo. –

Respuesta

7

Utilice un operador de mod para actualizar solo en 5, 10 o 20%. Llamas constantemente a OngressUpdate() durante la descarga.

if (downloadedSize % (totalSize/20) == 0) { // 20 updates every 5%, 10 every 10% and 5 every 20%, etc. 
    publishProgress((downloadedSize/totalSize) * 100); 
} 
+1

¡Salud! Mientras que su código no funcionaba en mi caso, lo adapté a mi 'publishProgress() 'comprobando si el' downloadSize' desde la última actualización de la notificación fue más grande que el 5% de 'totalSize'. Funciona muy bien ahora, ¡salud! – jsw

+1

¡Me apuntaste en la dirección correcta! ¡Muchas gracias! Ten una galleta –

Cuestiones relacionadas