在从互联网下载数据所花费的时间期间,在 AsyncTask 的 onProgressUpdate 中显示确定的 ProgressBar

Show determinate ProgressBar in onProgressUpdate of AsyncTask during the time taken to download data from the internet

我正在尝试使用 this library 在 AsyncTask 的 onProgressUpdate() 中的 Activity 屏幕上发布进度,该任务用于从 Internet 下载一些数据。他们提供的演示应用程序使用 Handler 来演示这一点。我需要在 AsyncTask 中使用它。

以下代码片段来自其演示应用程序中的代码。

我的问题是:

  1. onProgressUpdate 获取参数 Progress... values,并且 根据 documentation,它是“指示 进步。”但是 我不明白这是什么意思,也不知道我该如何 使用这个参数。 在我看到的例子中,他们正在做 类似于:

    progressBar.setProgress(Integer.parseInt(values[0]));
    

    为什么他们只使用传递数组中的第一个值 (值[0])?

  2. AsyncTask 怎么知道需要多长时间才能完成 下载操作。我想显示 ProgressBar 的进度 完成下载所用时间的值 0 到 100 手术。

    通过 progressBarDeterminate.setVisibility(View.VISIBLE) onPreExecute 正在做 progressBarDeterminate.setVisibility(View.GONE)onPostExecute,我们确保它仅在数据为 正在下载,但我们如何确保它从 从起始位置到最终位置 下载数据(当我们不知道它到底有多长时 要下载数据) ?

来自演示示例的代码(它使用 Handler,但我需要在 AsyncTask 中执行此操作)

public class MainActivity extends AppCompatActivity {
    ProgressBarDeterminate progressBarDeterminate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        progressBarDeterminate = (ProgressBarDeterminate) findViewById(R.id.progressDeterminate);

        progressTimer.start();
    }


        Thread progressTimer = new Thread(new Runnable() {

                @Override
                public void run() {
                    for(int i = 0; i <= 100; i++){
                        try {
                            Thread.sleep(30);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        handler.sendMessage(new Message());
                    }
                }
            });

            Handler handler = new Handler(new Handler.Callback() {
                int progress = 0;
                @Override
                public boolean handleMessage(Message msg) {
                    progressBarDeterminate.setProgress(progress++);
                    return false;
                }
            });
}

在回答您的第一个问题时,onProgressUpdate() 采用了一个 varargs 参数。这意味着它可以接受不定数量的指定类型的参数。例如:

public void someMethod(String... args) {
    //...
}

可以这样称呼,someMethod("Hi!"),或者这样称呼 someMethod("Hi", "there", "welcome", "to", "SO")

有关 varargs 的更多信息,请参见 here。这些参数的访问方式与访问数组的方式相同。如果那里只有一个参数,那么你可以使用 args[0].

编辑: 关于你的第二个问题,Android 开发人员 javadocs:

中有一个很好的例子
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

也就是说,答案真的取决于你的情况。在上面的例子中说你需要下载十个 URL。 for 循环被设置为按顺序下载每个 URL,一旦 URL 完成,将调用 publishProgress(),将当前值转换为百分比数字,(i / (float) count) * 100)。希望这能回答您的问题!