我有一段下载文件的代码。这发生在SwingWorker doInBackground方法中。 (参见下面的代码)file是一个File对象(temp dir),连接是一个URLConnection对象,它保存要下载的文件的url。 (url.openConnection()) 除了取消...
之外,下载在SwingWorker中正常工作SwingWorker<Integer,Integer> swingWorker = new SwingWorker<Integer,Integer>() {
int contentLength = 0;
int bytesDownloaded = 0;
double speed = 0;
@Override
protected Integer doInBackground() throws Exception {
setStatus("Dowloading...");
URL url = null;
URLConnection connection = null;
try {
url = new URL(MainScreen.getUrl()); // Gets a URL entered earlier to dowload
connection = url.openConnection();
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
BufferedOutputStream outputStream = null;
try {
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
outputStream = new BufferedOutputStream(new FileOutputStream(doelBestand));
contentLength = connection.getContentLength();
long start = System.nanoTime();
final double nanosPerSecond = 1000000000.0;
final double bytesPerMB = 1024 * 1024;
while(true) {
int b = inputStream.read();
bytesDownloaded += b;
speed = nanosPerSecond / bytesPerMB * bytesDownloaded / (System.nanoTime() - start + 1);
process();
if (b == -1 || Thread.interrupted()) {
break;
}
outputStream.write(b);
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
} finally {
try {
if(outputStream != null) {
outputStream.close();
}
} catch (IOException ex) { }
try {
if(connection != null) {
connection.getInputStream().close();
}
} catch (IOException ex) { }
}
return 100;
}
@Override
protected void done() {
progressBar.setIndeterminate(false);
progressBar.setValue(100);
lblPercent.setText("100 %");
btnStartCancel.setEnabled(false);
btnOpenFolder.setEnabled(true);
chkCloseOnFinish.setEnabled(false);
state = State.DONE;
}
protected void process() {
DecimalFormat df = new DecimalFormat("0.##");
if(speed > 0) {
lblDownloadSpeed.setText(df.format(speed) + " mb/s");
}
if(contentLength > 0) {
Integer percent = (int) (bytesDownloaded / (contentLength / 100.0));
progressBar.setValue(percent);
lblPercent.setText(percent + " %");
} else {
progressBar.setIndeterminate(true);
}
}
};
但是当用户按下“开始/取消”按钮时,程序的状态是“下载”。我正在调用swingWorker.cancel(true);
方法。
switch(state) {
case READY:
state = State.DOWNLOADING;
btnStartCancel.setText("Cancel");
swingWorker.execute();
break;
case DOWNLOADING:
swingWorker.cancel(true);
progressBar.setIndeterminate(false);
lblPercent.setText("Download was cancelled by the user.");
btnStartCancel.setText("Start");
btnStartCancel.setEnabled(true);
break;
case DONE:
// Do nothing
break;
}
但是isInterrupted()
总是返回false,所以它继续运行线程,但是cancel函数确实返回true。
我也尝试了while(!isCancelled())
,但这也会继续返回false。
还有一个问题,当它被取消时,它永远不会停止,所以它变成了一个无限的线程。 (int b继续运行被添加,bytesDownloaded将增长和增长)。只要在没有取消的情况下完成下载(然后b将为-1)并且循环将中断,它就不是无限的。
如何确保swingWorker中止下载?