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 
  • 相关阅读:
    [翻译] AAPullToRefresh
    [翻译] DKTagCloudView
    【转】Data URL和图片,及Data URI的利弊
    【转】C#获取当前日期时间(转)
    【转】Android的setTag
    【转】Android之Adapter用法总结
    【转】jpg png区别和使用
    【转】Android UI开发第三十一篇——Android的Holo Theme
    【转】android中的Style与Theme
    【转】关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题
  • 原文地址:https://www.cnblogs.com/yangzhenyu/p/2176367.html
Copyright © 2011-2022 走看看