2015-09-05 48 views
0

我想在後臺複製文件並每隔n秒更新一次進度。Android AsyncTask每秒複製並更新

現在,當新百分比大於先前百分比時,下面的代碼會更新進度。這對於小文件來說是分崩離析的,因爲它速度很快並且落後於UI線程。

所以我的問題是如何複製背景中的文件,但每n秒發佈一次進度。另外我怎樣才能計算它的複製速度?

的什麼,我試圖模仿是一個下載通知一個很好的例子,它顯示的速度,比例,並在〜2000毫秒間隔

這是我使用複製的代碼更新它們,在doInBackground()方法

startTime = System.currentTimeMillis(); 
    FileInputStream input = null; 
    FileOutputStream output = null; 
    totalMegaBytes = new File(source).length(); 
    try { 
     input = new FileInputStream(source); 
     output = new FileOutputStream(dest); 
     byte [] buffer = new byte[8192]; 
     int length; 
     while ((length = input.read(buffer)) > 0) { 
      total += length; 
      latestPercentDone = (int) ((total/(float) totalMegaBytes) * 100); 
      if (percentDone != latestPercentDone) { 
       percentDone = latestPercentDone; 
       publishProgress(""+percentDone); 
      } 
      output.write(buffer, 0, length); 
     } 
     //flush remaning information 
     output.flush(); 
     //close stream 
     output.close(); 
     input.close(); 
+0

你一定要考慮的Rx對於這種或者問題,這將是很容易做到這一點:https://github.com/davidmoten/rxjava-file –

回答

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"); 
+0

這將先等待半秒,但隨後每循環發佈一次進度。 –

+0

這只是一個大方向。但無論如何修復它,只是爲了安全起見。謝謝。 –

+0

@RobMeeuwisse:每次調用'publishProgress()'後都會更​​新'startTime'。 – cybersam

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); 
}