我想在后台复制一个文件,并且每隔n秒更新一次进度。
现在,当新百分比大于之前的百分比时,下面的代码会更新进度。这对于小文件来说是分崩离析的,因为它变得如此之快并且滞后于UI线程。
所以我的问题是如何在后台复制文件,但每隔n秒发布一次进度。另外,我如何计算复制的速度?
我试图模仿的一个很好的例子是下载通知,它显示速度,百分比并以〜2000ms间隔更新它们
这是我用来复制process(INPUTS)
begin
<your code>
end process;
方法
doInBackground()
答案 0 :(得分:2)
您可以减少publishProgress
来电,并仅在预定义的时间间隔内调用。
只需添加更新的最短时间间隔即可。例如,这将以最多半秒的速率更新:
private static long UPDATE_DELAY = 500; // Delay in millis
// Start with 0 progress
publishProgress("0");
...
long currentTime = System.currentTimeMillis();
if ((currentTime - startTime > UPDATE_DELAY) &&
(percentDone != latestPercentDone)) {
percentDone = latestPercentDone;
publishProgress(""+percentDone);
startTime = currentTime;
}
...
// End with 100 progress
publishProgress("100");
答案 1 :(得分:0)
基本上每隔一段时间报告一次的方法就是使用这样的循环:
long reportTime = System.currentTimeMillis(); // first report after first processing
while (!done) {
// do processing
if (System.currentTimeMillis() >= reportTime) {
// do progress report
reportTime = System.currentTimeMillis() + 2000; // next report in 2 secs
}
}
计算复印速度可以采用不同的方式。最简单的方法是划分当前运行时复制的当前字节:
long startTime = System.currentTimeMillis();
long totalBytesCopiedSoFar = 0;
while (!done) {
// do processing, and update totalBytesCopiedSoFar
if (itIsReportingTime) {
long runTimeSoFarInMillis = System.currentTimeMillis() - startTime;
long runTimeSoFarInSecs = runTimeSoFarInMillis / 1000;
double copyingSpeedInBytesPerSec = (double) totalBytesCopiedSoFar / (double) runTimeSoFarInSecs;
}
}
将两种模式组合并将其应用于您的代码,可以得到以下结果。我已经省略了您的设置并清理了代码,所以这不会编译,但您可以理解。
long startTime = System.currentTimeMillis();
long reportTime = System.currentTimeMillis(); // first report as soon as possible
long totalMegaBytes = new File(source).length();
while ((length = input.read(buffer)) > 0) {
total += length;
latestPercentDone = (int) ((total / (float) totalMegaBytes) * 100);
long runTimeInSecs = (System.currentTimeMillis() - startTime) / 1000;
double speedInBytesPerSec = (double) total / (double) runTimeInSecs;
if (System.currentTimeMillis() >= reportTime) {
publishProgress(""+latestPercentDone); // you may want to report the speed as well
reportTime = System.currentTimeMillis() + 2000; // next report in 2000 ms
}
output.write(buffer, 0, length);
}