如何强制关闭从HttpUrlConnection获取的InputStream?

时间:2015-11-02 08:30:22

标签: android android-asynctask inputstream httpurlconnection

我刚刚实现了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;
}

0 个答案:

没有答案