I just implemented a HTTP Downloader. It has 4 button to do some operation: start, pause, resume, cancel download. When pressing pause or cancel button, I use AsyncTask.cancel()
to cancel the download AsyncTask
and disable all UI widget temporarily. When AsyncTask
onCancelled
triggers, I enable the UI widget.
Here's a question: I found inputStram.close()
somehow is very slow sometimes. Cause it is called before onCancelled()
, it will block UI for a while. I found some article discussed about it but none of their answer really work. It confuses me so bad...
Related questions:
Sometimes HttpURLConnection.getInputStream executes too slowly
InputStream won't close, or takes forever to
Below is my code in AsyncTask
. Wish someone give some help. I will appreciate that a lot.
@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;
}