在listview中更新android进度条的进度

在listview中更新android进度条的进度,android,android-listview,android-asynctask,android-progressbar,android-download-manager,Android,Android Listview,Android Asynctask,Android Progressbar,Android Download Manager,我正在使用android下载管理器下载文件。文件是多个的,我正在listview中显示它们的进度。我的代码运行良好,但当我的下载量超过4或5次时,listview会变得非常慢,事实上整个应用程序都会变慢。过了一会儿它就卡住了,我不得不强行关上,因为手机也被挂了。 这是我更新listview的代码 private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> { boolean isRunning = t

我正在使用android下载管理器下载文件。文件是多个的,我正在listview中显示它们的进度。我的代码运行良好,但当我的下载量超过4或5次时,listview会变得非常慢,事实上整个应用程序都会变慢。过了一会儿它就卡住了,我不得不强行关上,因为手机也被挂了。 这是我更新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();
        }

    }
}

我完全陷入困境,不知道我错在哪里,请帮助我。任何帮助都将不胜感激。谢谢:)

线程。睡眠(16)。16毫秒?这很短。onProgressUpdate将花费更多的时间。但更重要的是:如果您经常调用publishProgress(),它们都将叠加为onProgressUpdate,只有在操作系统有时间在UI线程上执行此操作时,才会调用onProgressUpdate。只要稍加调整,您就可以避免过早调用publishProgress()。向asynctask添加一个
volatile boolean progressBusy=false在调用publishProgress()之前将其设置为true。在onProgressUpdate中将其再次设置为false。在doInBackground中,如果progressBusy为true,则不要调用publishProgress()。

从您提供给我们的小代码中可以看出

首先,对于大多数情况,您并没有调用stop()方法,所以我假设您被锁定在一个无限循环中

 public void stop() {
        isRunning = false;
    }
关于如何正确且可读地有效地使用AsyncTask类,他们有一个出色的例子


希望有帮助。

我已将progressBusy设置为true;在doInBackground中的publishProgress()之前,如果progressBusy为true,我不会调用publishProgress()。但目前进展情况尚未更新:(我知道它正在工作,并且在一定程度上得到了改进,但问题仍然存在。我将按照您所说的那样编辑代码。请看一看
progressBusy=false;
。您在onProgressUpdate中将其作为第一条语句。这是错误的位置。如果使用200毫秒,则不会有任何帮助。您应该将其作为最后一条语句。当代码完成了。我在最后添加了它,但没有运气:(我应该使用多少时间?首先测量onProgressUpdate的执行时间。但同时从2000或更多开始。那里有耗时的代码。它可能受益于多核处理器。
 public void stop() {
        isRunning = false;
    }