【问题标题】:Double Progress Bars with update via AsyncTask通过 AsyncTask 更新的双进度条
【发布时间】:2014-02-27 10:26:39
【问题描述】:

我正在开发一个下载文件并显示 2 个进度条的应用,第一个显示当前下载文件,第二个显示基于文件数量的总进度。

我在我的应用程序中使用DoubleProgressBar 库:

我成功更新了第一个 ProgressBar,但卡住了第二个。

这是我的 AsyncTask 类代码:

private DoubleProgressDialog pDialog;

    class DownloadFileFromURL extends AsyncTask<String, Integer, String> {
        Context mContext;

        public DownloadFileFromURL(Context ctx) {
            // TODO Auto-generated constructor stub
            this.mContext = ctx;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(CUSTOM_PROGRESS_DIALOG);
        }

        /* Downloading file in background thread */
        @Override
        protected String doInBackground(String... f_url) {

            InputStream input = null;
            OutputStream output = null;
            HttpURLConnection connection = null;

            try {
                URL url = new URL(f_url[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                // getting file length
                int fileLength = connection.getContentLength();
                for (int i = 0; i <= ArrayOfFiles.length; i++){
                File f = new File(Environment.getExternalStorageDirectory() + "/Folder/", ArrayOfFiles[i]);

                // input stream to read file - with 8k buffer
                input = new BufferedInputStream(url.openStream(), 8192);
                // Output stream to write file
                output = new FileOutputStream(f); 

                byte data[] = new byte[8192];

                long total = 0;
                int count;
                int EntireProgress = 0;
                while ((count = input.read(data)) != -1) {
                    // allow canceling with back button
                    if (isCancelled()) {
                        input.close();
                        return null;
                    }
                    total += count;
                    // publishing the progress....
                    if (fileLength > 0) // only if total length is known
                    publishProgress((int)(total * 100 / fileLength));
                    output.write(data, 0, count);

                        /*Here is my trouble, the 2nd ProgressBar is updating as the same of the first one, I need the 2nd one to update itself slowly till all files get downloaded*/
                    int CurrentProgress = pDialog.getProgress();
                    pDialog.setSecondaryProgress(CurrentProgress );
                    publishProgress(CurrentProgress );

                }

            } catch (Exception e) {
                return e.toString();
            } finally {
                try {
                    if (output != null)
                        output.close();
                    if (input != null)
                        input.close();
            }
                } catch (IOException ignored) {
                }

                if (connection != null)
                    connection.disconnect();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            // dismiss the dialog after the file was downloaded
            dismissDialog(CUSTOM_PROGRESS_DIALOG);

            if (result != null)
                Toast.makeText(mContext,"Download error: " + result, Toast.LENGTH_LONG).show();
            else
                Toast.makeText(mContext,"File downloaded", Toast.LENGTH_SHORT).show();  
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            // if we get here, length is known, now set indeterminate to false
            pDialog.setIndeterminate(false);
            pDialog.setMax(100);
            pDialog.setProgress(progress[0]);
        }

    }

我也在我的活动类中使用了这个方法:

    @Override
        protected Dialog onCreateDialog(int id) {
            switch (id) {
            case CUSTOM_PROGRESS_DIALOG:
                pDialog = new DoubleProgressDialog(NetworkActivity.this);
                pDialog.setMessage("Downloading file. Please wait...");
                pDialog.setMax(100);
                pDialog.setIndeterminate(true);
                pDialog.setCancelable(false);
                pDialog.setButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.cancel();
                    }
                });
                pDialog.show();
                return pDialog;
            default:
                return null;
            }
        }

有什么想法吗?

【问题讨论】:

  • publishProgress(CurrentProgress ); 这个方法有什么作用? ALSO:您只处理一个文件,但想根据多个文件更新第二个进度?
  • 尝试将pDialog.setSecondaryProgress(CurrentProgress ); 移动到onProgressUpdate(Integer... progress)。由于您正在从可能是问题的非 UI 线程更新 UI
  • @cosmincalistru ,可以从 doInBackground(Params...) 调用此方法,以便在后台计算仍在运行时在 UI 线程上发布更新。每次调用此方法都会触发 UI 线程上 onProgressUpdate(Progress...) 的执行。如果任务被取消,onProgressUpdate(Progress...) 将被调用。将更新我的代码以下载多个文件。
  • @super-qua ,它可以工作,但是一旦第一个文件下载,第二个 ProgressBar 会自行重置,然后它通常会再次与第二个文件一起计数,然后在完成时重置,任何想法,即如何保存第一个文件的当前进度并在第二个文件下载时加起来?
  • 您在主Activity 中声明了“DownloadFileFromUrl”类?还是一个单独的类?

标签: android android-asynctask android-progressbar


【解决方案1】:

第一部分是将pDialog.setSecondaryProgress 移动到onProgressUpdate(Integer... progress) 方法。
您还通过将其设置为CurrentProgress(设置为pDialog.getProgress();)来重置每个下载任务中的次要进度。因此,下载完成后,第二个进度总是会被重置。

编辑:

// publishing the progress....
if (fileLength > 0) // only if total length is known
    publishProgress((int)(total * 100 / fileLength), pDialog.getSecondaryProgress());

(...)

int CurrentProgress = pDialog.getProgress();

// do not update secondary progress here
// pDialog.setSecondaryProgress(CurrentProgress );
int secondaryProgress = (CurrentProgress + 100 * i)/ArrayOfFiles.length;
publishProgress(CurrentProgress, secondaryProgress);

还有 onProgressUpdate

@Override
protected void onProgressUpdate(Integer... progress) {
   super.onProgressUpdate(progress);

   (...)       

   pDialog.setProgress(progress[0]);
   pDialog.setSecondaryProgress(progress[1]);

}

【讨论】:

  • 我试过这个,但是第二个 ProgressBar 很快填满并停留在 100%,:(
  • 第二个 ProgressBar 的最大值是多少?
  • 如果我明白你的意思,我认为是通过 xml?如果是那么,我为我的 ProgressBars 设置没有最大值,如果没有,那么在我的代码中,只有 1 个 ProgressBar 具有主要和次要进度,所以,我只为我的 pDialog 设置MAx
  • 啊,好吧,我以为你可以设置一个最大值。在这种情况下,您必须将第二个 ProgressBar 的进度除以文件数。我更新了我的答案
  • 还是一样,我做到了,但现在延迟了一段时间,然后很快就被填满了:(
【解决方案2】:

如果您没有在主课之外设置DownloadFileFromUrl,我建议您这样做

int CurrentProgress = pDialog.getProgress();
int secondaryProgress = (CurrentProgress + 100 * id_treated_file)/number_of_files;
// id_treated_file - 0, 1, 2, ... , number_of_files - 1
pDialog.setSecondaryProgress(CurrentProgress);
// secondaryProgress will be progress[1] in your onProgressUpdate method
publishProgress(CurrentProgress, secondaryProgress);

您的 onProgressUpdate 方法应该如下所示:

@Override
protected void onProgressUpdate(Integer... progress) {
    super.onProgressUpdate(progress);
    // if we get here, length is known, now set indeterminate to false
    pDialog.setIndeterminate(false);
    pDialog.setMax(100);
    pDialog.setProgress(progress[0]);
    pDialog.setSecondaryProgress(progress[1]);
}

编辑
或者你可以试试

 pDialog.setSecondaryProgress((progress[0] + 100 * id_treated_file)/number_of_files);

【讨论】:

  • 行:pDialog.setSecondaryProgress(progress[1]);给我 ArrayIndexOutOfBound 因为只有 0 索引值,但是,如果我将其修改为: pDialog.setSecondaryProgress(progress[0]/NumOfFiles); ,它可以工作,但它会在每个文件下载任务中自行重置
  • 如果您使用id_treated_file 的当前文件号和number_of_files 的总处理文件数,这应该可以工作
猜你喜欢
  • 1970-01-01
  • 2019-01-08
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多