Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freezing UI Thread with AsyncTask

Tags:

android

I'm trying to use an AsyncTask to download a file with a notification progress. Everything works fine (downloads in background thread), except whenever I add the code to update the progress bar through publishProgress(), it freezes the whole phone, until the download is finished and the notification shows "Download Completed".

I'm completely lost as to why this is the case, but I am maybe thinking it's along the lines of the publishProgress((downloadedSize / totalSize) * 100) that i'm using?

Anyways here is the 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);
    }

I'm really stuck on this one - Any help would be appreciated. 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);
        }
    }
like image 777
jsw Avatar asked Jun 02 '11 02:06

jsw


1 Answers

Use a mod operator to only update on 5, 10 or 20 %. You're calling onProgressUpdate() constantly during the download.

if (downloadedSize % (totalSize / 20) == 0) { // 20 updates every 5%, 10 every 10% and 5 every 20%, etc.
    publishProgress((downloadedSize / totalSize) * 100);
}
like image 174
Bill Mote Avatar answered Oct 22 '22 20:10

Bill Mote