我刚刚实现了HTTP下载程序。它有4个按钮来做一些操作:启动,暂停,恢复,取消下载。按暂停或取消按钮时,我使用AsyncTask.cancel()
取消下载AsyncTask
并暂时禁用所有UI小部件。当AsyncTask
onCancelled
触发时,我启用了UI小部件。
这是一个问题:我发现inputStram.close()
有时会非常缓慢。因为它在onCancelled()
之前调用,它会阻止UI一段时间。我发现了一些关于它的文章,但他们的答案都没有真正起作用。这让我很困惑......
相关问题:
Sometimes HttpURLConnection.getInputStream executes too slowly
InputStream won't close, or takes forever to
以下是AsyncTask
中的代码。希望有人给予一些帮助。我会很感激。
@Override
protected String doInBackground(URL... urls) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection httpURLConnection = null;
try {
URL url = urls[0];
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(CONNECT_TIMEOUT);
httpURLConnection.setInstanceFollowRedirects(true);
httpURLConnection.setRequestProperty("Range", "bytes=" + mDownloadedBytes + "-");
httpURLConnection.setUseCaches(false);
httpURLConnection.setReadTimeout(5000);
httpURLConnection.setRequestProperty("Connection", "close");
System.setProperty("http.keepAlive", "false");
httpURLConnection.connect();
if (!(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK // 200
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_CREATED // 201
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED // 202
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_AUTHORITATIVE // 203
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT // 204
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_RESET //205
|| httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL)) { //206
return "Download fail, server returned HTTP " + httpURLConnection.getResponseCode()
+ " " + httpURLConnection.getResponseMessage();
}
String fileName = getFileName();
String fileExtension = getFileExtension(httpURLConnection);
if(mDownloadFile == null) {
mDownloadFile = getDownloadFile(fileName, fileExtension);
output = new FileOutputStream(mDownloadFile);
} else {
if(mDownloadFile.exists()) {
output = new FileOutputStream(mDownloadFile, true);
} else {
cancel(true);
return null;
}
}
int fileLength = httpURLConnection.getContentLength();
if(sTotalFileLength == -1 && fileLength != -1){
sTotalFileLength = fileLength;
}
// update download state depending on fileLength
updateUI(fileLength);
// check free space if server respond this value
if(fileLength != -1){
if(!isFreeSpaceEnough(fileLength)){
return "Download fail, you don't have enough free space to save the file";
}
}
// download the file
input = httpURLConnection.getInputStream();
byte data[] = new byte[BUFFER_SIZE];
int count;
while ((count = input.read(data)) != -1) {
if (isCancelled()) {
return null;
}
mDownloadedBytes += count;
if(sTotalFileLength > 0){
int progress = (int)(mDownloadedBytes * 100 / sTotalFileLength);
publishProgress(progress);
}
try {
output.write(data, 0, count);
} catch (IOException e){
return "No enough free space to save file!";
} catch (IndexOutOfBoundsException e){
return "Write to file error";
}
}
// write a record to Download DB after download complete
// just record image in DownloadDb
if(!fileExtension.equals("") && isInImageExtensionList(fileExtension)) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mDbRow = new DownloadDbRow(dateFormat.format(new Date()), fileName+"."+fileExtension);
mDb.insert(mDbRow);
}
// Tell system to scan for media file change
mMediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(mDownloadFile);
mMediaScanIntent.setData(contentUri);
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null) {
output.flush();
output.close();
}
/////////////////////
// //
// problems here!! //
// //
/////////////////////
if (input != null) {
input.close();
}
} catch (IOException e) {
return e.toString();
}
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
return DOWNLOAD_SUCCESSFULLY;
}