update progress of android progress bar inside listview

1.1k Views Asked by At

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 :)

2

There are 2 best solutions below

10
On BEST ANSWER

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.

0
On

Well from what I can see from the little code you have provided us,

first and for most, you are not calling your stop() method any ware so I assume you are locked in an infinite loop.

 public void stop() {
        isRunning = false;
    }

On Google's Android Developer Documentation site they have an outstanding example on how to effectevly use AsyncTask class correctly and readable.

Hope it helps.