更新进度对话框

3

我正在尝试制作一个应用程序,可以帮助我评估从网络资源下载文件所需的时间。我找到了两个样例:

使用Android下载文件,并在ProgressDialog中显示进度

以及

http://www.helloandroid.com/tutorials/how-download-fileimage-url-your-device

第二个示例显示了更短的下载时间,但我不知道如何使用它来更新进度对话框。我认为在第二种情况下应该对“while”表达式进行一些处理,但我找不到方法。有人能给我任何建议吗?
UPD:
第1段代码:
try {
            time1 = System.currentTimeMillis();
            URL url = new URL(path);
            URLConnection conexion = url.openConnection();
            conexion.connect();
            // this will be useful so that you can show a tipical 0-100% progress bar
            int lenghtOfFile = conexion.getContentLength();
            // downlod the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream("/sdcard/analyzer/test.jpg");

            byte data[] = new byte[1024];

            long total = 0;

          time11 = System.currentTimeMillis();
           while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int)(total*100/lenghtOfFile));
                output.write(data, 0, count);
            }
            time22= System.currentTimeMillis()-time11;
            output.flush();
            output.close();
            input.close();


        } catch (Exception e) {}

        timetaken = System.currentTimeMillis() - time1;

第二段代码:

       long time1 = System.currentTimeMillis();
        DownloadFromUrl(path, "test.jpg");
        long timetaken = System.currentTimeMillis() - time1;

在哪里

  public void DownloadFromUrl(String imageURL, String fileName) {  //this is the downloader method
 try {
         URL url = new URL(imageURL); //you can write here any link
         File file = new File(fileName);

        /*Open a connection to that URL. */
         URLConnection ucon = url.openConnection();

         /*
          * Define InputStreams to read from the URLConnection.
          */
         InputStream is = ucon.getInputStream();
         BufferedInputStream bis = new BufferedInputStream(is);

         /*
          * Read bytes to the Buffer until there is nothing more to read(-1).
          */
         ByteArrayBuffer baf = new ByteArrayBuffer(50);
         int current = 0;
         while ((current = bis.read()) != -1) {
                 baf.append((byte) current);
         }

         /* Convert the Bytes read to a String. */
         FileOutputStream fos = new FileOutputStream(PATH+file);
         fos.write(baf.toByteArray());
         fos.close();

 } catch (IOException e) {
         Log.d("ImageManager", "Error: " + e);
 }

所以问题在于第一种方法似乎要慢30%左右。

2个回答

2
第二个例子可能运行得更快,但它会独占GUI线程。使用AsyncTask的第一种方法更好;它允许GUI在下载过程中保持响应性。
我发现将AsyncTask与SwingWorker进行比较是很有帮助的,正如这个例子所示。

我在Asynctask中执行第二个方法。 - StalkerRus
第一段代码有1024字节的缓冲区,而第二段只有50个。 - trashgod
我尝试将缓冲区减少到50,但是性能没有任何改变。 - StalkerRus
你说,“第一段代码下载文件的速度大约慢了30%”,而“第一种方法似乎比较快,快了约30%”。这似乎是矛盾的。我注意到AsyncTask必须与GUI交替操作以显示进度,因此30%似乎是可信的。 - trashgod
抱歉,我已经纠正了错误。是否可以将第二段代码插入到Asynctask中并更新进度对话框?或者在这种情况下,我只会有相同的性能下降?或者我可以改进第一段代码的性能吗? - StalkerRus
显示剩余2条评论

1

第一个链接是最好的。但我不能在周一提供代码(它在家里的电脑上),或者稍后我可以提供完整的功能。但是:

private class DownloadFile extends AsyncTask<String, Integer, String>{
    @Override
    protected String doInBackground(String... url) {
        int count;
        try {
            URL url = new URL(url[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();
            // this will be useful so that you can show a tipical 0-100% progress bar
            int lenghtOfFile = conexion.getContentLength();

            // downlod the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext");

            byte data[] = new byte[1024];

            long total = 0;

            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int)(total*100/lenghtOfFile));
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {}
        return null;
    }

这个类(在我看来)很好。`publishProgress` 是一个简单的函数,其中您最多有两行。设置 `max` 和设置 `current`。正如您在此代码中所看到的 `lengthOfFile` 表示文件有多少字节。`total` 表示当前进度(例如 25/100 字节)。运行此类很容易:`DownloadFile a = new DownloadFile(); a.execute(value,value);//如果不使用 value,则为 null。`希望你明白我,我的英语不好。

我理解它的工作原理,但我发现使用第一段代码下载文件的速度大约比使用第二段代码慢30%。我无法理解为什么。 - StalkerRus
byte data[] = new byte[1024]; 你需要在这里设置新值,例如16000。这将增加下载速度。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接