Search code examples
androidandroid-listviewandroid-asynctaskandroid-progressbarandroid-download-manager

update progress of android progress bar inside listview


I'm downloading files by using android download manager. Files are multiple, and I'm showing their progress inside of listview. my code is working fine but when my downloads gets more than 4 or 5 the listview gets very slow, infact the whole app gets slow. In a few moment it gets stuck and I've to forcibly close because phone also gets hanged. here is my code to update listview.

private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> {

    boolean isRunning = true;
    boolean progressBusy = false;
    public void stop() {
        isRunning = false;
    }

    @Override
    protected Void doInBackground(Void... params) {
        while (isRunning) {


            if(progressBusy==true){

            }
            else{
                progressBusy = true;
                publishProgress();
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Void... params) {
        super.onProgressUpdate();
        try {
            progressBusy = false;
            if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                int start = Lv_DownloadItems.getFirstVisiblePosition();
                for (int i = start, j = Lv_DownloadItems
                        .getLastVisiblePosition(); i <= j; i++) {
                    View view = Lv_DownloadItems.getChildAt(i - start);
                    DownloadManager.Query q = new DownloadManager.Query();
                    q.setFilterById(Long.parseLong(progress_ids
                            .get(i)));
                    final Cursor cursor = downloadManager.query(q);
                    cursor.moveToFirst();

                    long bytes_downloaded = cursor
                            .getInt(cursor
                                    .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                    int bytes_total = cursor
                            .getInt(cursor
                                    .getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

                    int len1 = (int)(bytes_downloaded * 100 / bytes_total);

                    int columnIndex = cursor
                            .getColumnIndex(DownloadManager.COLUMN_STATUS);

                    ProgressBar progress = (ProgressBar) view
                            .findViewById(R.id.progressBar1);
                    progress.setProgress(len1);

                    TextView txtStatus = (TextView) view
                            .findViewById(R.id.percentage);
                    // txtStatus.setPadding(10, 0, 0, 0);
                    txtStatus.setText(String.valueOf(len1) + "%");
                    cursor.close();


                }
            }

        } catch (Exception ec) {
            ec.printStackTrace();
        }

    }
}

I call this async task at onResume

UpdaterAsyncTask mUpdater = new UpdaterAsyncTask();
            mUpdater.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
                    (Void) null);

I'm totally gets stuck and don't know where i'm wrong, please help me. Any help would be much appreciated. thank you :)


Solution

  • Thread.sleep(16);. 16 ms ? That is short. onProgressUpdate will take much more time than that. But what is more: if you call publishProgress() so often they will all stack up as onProgressUpdate will only later get called when the OS has time to do that on the UI thread. With a little adaptation you can prevent an to early calling of publishProgress(). Add to the asynctask avolatile boolean progressBusy = false; Set it to true before calling publishProgress(). Set it to false again in onProgressUpdate. In doInBackground do not call publishProgress() if progressBusy is true.