zoukankan      html  css  js  c++  java
  • Http协议的下载功能

          采用HttpClient组件实现Http下载,具有一些特有的优势。尽管java.net包提供了基本通过HTTP访问资源的功能,但它没有提供全面的灵活性和其它很多应用程序需要的功能。HttpClient就是寻求弥补这项空白的组件,通过提供一个有效的,保持更新的,功能丰富的软件包来实现客户端最新的HTTP标准和建议。

          很多时候,单一的下载并不能满足我们的需要,而必须采用多线程的机制。但是众所周知,线程的创建和销毁都是需要开销的,例如,若同时打开几十个下载线程,这对系统的资源消耗是十分大的。我们可以采取线程池的方式,让池中下载的线程数目一定,这样就能做到高效的下载。

    下载实现代码如下:

    package com.yzy.downloader;
     
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Environment;
    import android.util.Log;
     
    public class DownloadManager {
        // 下载地址
        private String url;
        // 下载任务线程池
        private ExecutorService executorService;
        // 应用程序上下文
        private Context context;
     
        public DownloadManager(Context context) {
            super();
            this.context = context;
        }
     
        public void addTask(String url, DownloadItem item) {
            this.url = url;
            executorService.submit(new DownloadThread(item));
        }
     
        public void stop() {
            executorService.shutdown();
        }
     
        public void start() {
            // 创建线程池
            executorService = Executors.newFixedThreadPool(5);
        }
     
        public boolean isStop() {
            return executorService.isShutdown();
        }
     
        class DownloadThread implements Runnable {
            // 已经下载的字节数
            private long finished;
            // 文件总的字节数
            private long fileLength;
            // 文件ID号
            private String fileId;
            // 文件存储位置
            private File downloadFile;
     
            public DownloadThread(DownloadItem item) {
                fileId = item.getFileId();
                finished = item.getFileLength();
                File sdFile = Environment.getExternalStorageDirectory();
                downloadFile = new File(sdFile + File.separator + "image" + fileId
                        + ".png");
                if (!downloadFile.exists()) {
                    try {
                        downloadFile.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
     
            @Override
            public void run() {
                Log.v("tag", "fileId=" + fileId + ",fileLength=" + fileLength);
                try {
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet(DownloadManager.this.url);
                    HttpResponse httpResponse = httpClient.execute(httpGet);
                    HttpEntity httpEntity = httpResponse.getEntity();
                    fileLength = httpEntity.getContentLength();
                    Log.v("tag", "查询得到文件大小为: " + fileLength);
                    httpClient.getConnectionManager().shutdown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet(DownloadManager.this.url);
                    httpGet.addHeader("Range", "bytes=" + finished + "-"
                            + (fileLength - 1));
                    HttpResponse httpResponse = httpClient.execute(httpGet);
                    HttpEntity httpEntity = httpResponse.getEntity();
                    FileOutputStream outputStream = new FileOutputStream(
                            downloadFile, true);
                    int count = 0;
                    int deltaCount = 0; // 增量
                    byte[] tmp = new byte[8 * 1024];
                    InputStream inputStream = httpEntity.getContent();
                    while (finished < fileLength) {
                        if (DownloadManager.this.executorService.isShutdown()) {
                            return;
                        }
                        count = inputStream.read(tmp);
                        finished += count;
                        deltaCount += count;
                        outputStream.write(tmp, 0, count);
                        if (Float.parseFloat(Integer.toString(deltaCount))
                                / Float.parseFloat(Long.toString(fileLength)) > 0.05) {
                            deltaCount = 0;
                            Intent intent = new Intent("setProgressBar");
                            intent.putExtra("fileId", fileId);
                            int progressBarState = (int) (Float.parseFloat(Long
                                    .toString(finished))
                                    / Float.parseFloat(Long.toString(fileLength)) * 100);
                            intent.putExtra("progressBarState", progressBarState);
                            DownloadManager.this.context.sendBroadcast(intent);
                        }
     
                    }
                    outputStream.close();
                    httpClient.getConnectionManager().shutdown();
                    Intent intent = new Intent("setProgressBar");
                    intent.putExtra("fileId", fileId);
                    intent.putExtra("progressBarState", 100);
                    DownloadManager.this.context.sendBroadcast(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
     
    实现效果如下:
     
    device-2011-09-14-162523 
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/yangzhenyu/p/2176367.html
Copyright © 2011-2022 走看看