2

我正在使用 AsyncTask 将图像上传到网络服务器,当我引入更新进度条的方法时,它会减慢上传速度。但是如果没有进度条的循环更新器,它会在几秒钟内(非常快)上传图像。这是我用来更新进度条的代码:

  bufferSize = Math.min(bytesAvailable, maxBufferSize);
  mFileLen =  file.length();

  for (int i = 0; i < bufferSize; i++) {
                publishProgress((int) ((i / (float) mFileLen) * 100));
            } 

无论如何我可以更新进度条而不会导致操作变慢?

4

2 回答 2

2

提醒一下,您可以在 IntentService 中将数据发送到 Web 服务器,这也是异步的。如果用户不必立即处理操作结果,则首选 IntentService。这完全是背景。另一方面,您可以从中发布通知。问自己这些问题:

  1. 即使用户更改了设备方向,我是否希望此操作继续?(如果 Activity 被销毁,Asynctask 将停止;IntentService 不会)。
  2. 相反,我是否介意操作是否必须重新加载(AsyncTask 更简单一些)。
  3. 我是否存储持久数据(使用 IntentService 甚至绑定服务和 SyncAdapter)
  4. 用户是否需要在操作完成时留下来(如果是,AsyncTask 在完成时会提供更即时的反馈。如果不是,IntentService 与应用程序的活动有些断开,因此它可以在其他事情发生时愉快地搅动。
于 2013-09-26T01:12:58.100 回答
2

一些想法:

  1. 您不需要progressBar1在循环的每次迭代中设置最大值,这是没有意义的,因为bufferSize在循环内部不会改变。将该命令移到循环之外。
  2. 试着记住你以前的进步:prevProgress = (i / mFileLen)。然后衡量你的新进展:currProgress = (i / mFileLen)。然后,如果两个进度之间的差异不大于 0.01 (1%),则不要更新 UI:if (currProgress - prevProgress >= 0.01) publishProgress(...);

这是一个例子:

        float currProgress = 0;
        float prevProgress = 0;
        for (int i = 0; i < bufferSize; i++) 
        {
            currProgress = ((float)i / (float) mFileLen);

            if (currProgress - prevProgress >= 0.01)
            {
                publishProgress((int) (currProgress * 100));
                prevProgress = currProgress;
            }
        } 

当进度大于 2% (0.02) 而不是 1% (0.01) 等时,您可以通过更新 UI 来使其工作得更快。

另外,我觉得和之间没有真正的相关性i……mFileLen你的bufferSize?是否小于mFileLen(应该是)。在这种情况下,您应该使用一个单独的变量来计算它使用的整体进度,而不是i衡量进度。

希望这可以帮助。

于 2013-09-26T00:33:02.870 回答