zoukankan      html  css  js  c++  java
  • Android进阶篇单任务多线程断点下载

    异步下载类:

        class DownloadTask extends Thread{
            private int blockSize, downloadSizeMore;
            private int threadNum = 5;
            String urlStr, threadNo, fileName;
    
            /**
             * @param urlStr 下载的URL 
             * @param threadNum 下载的线程数
             * @param fileName 文件名
             */
            public DownloadTask(String urlStr, int threadNum, String fileName) {
                this.urlStr = urlStr;
                this.threadNum = threadNum;
                this.fileName = fileName;
            }
    
            @Override
            public void run() {
                FileDownloadThread[] fds = new FileDownloadThread[threadNum];
                try {
                    URL url = new URL(urlStr);
                    URLConnection conn = url.openConnection();
                    //获取下载文件的总大小
                    fileSize = conn.getContentLength();
                    //计算每个线程要下载的数据量
                    blockSize = fileSize / threadNum;
                    // 解决整除后百分比计算误差
                    downloadSizeMore = (fileSize % threadNum);
                    File file = new File(fileName);
                    for (int i = 0; i < threadNum; i++) {
                        //启动线程,分别下载自己需要下载的部分
                        FileDownloadThread fdt = new FileDownloadThread(url, file,
                                i * blockSize, (i + 1) * blockSize - 1);
                        fdt.setName("Thread" + i);
                        fdt.start();
                        fds[i] = fdt;
                    }
                    boolean finished = false;
                    while (!finished) {
                        // 先把整除的余数搞定
                        downloadedSize = downloadSizeMore;
                        finished = true;
                        for (int i = 0; i < fds.length; i++) {
                            downloadedSize += fds[i].getDownloadSize();
                            if (!fds[i].isFinished()) {
                                finished = false;
                            }
                        }
                        //通知handler去更新视图组件
                        Message msg = new Message();
                        msg.what = 1;
                        mHandler.sendMessage(msg);
                        //休息1秒后再读取下载进度
                        this.sleep(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    单个下载线程:

    /**
     * @author gongchaobin
     * 
     *     android多线程下载
     *  单个下载线程
     */
    public class FileDownloadThread extends Thread{
        private static final int BUFFER_SIZE=1024;
        private URL url;
        private File file;
        private int startPosition;//当前线程下载的起点
        private int endPosition;//当前线程下载的终点
        private int curPosition;
        private boolean finished=false;    //用于标识当前线程是否下载完成
        private int downloadSize=0;
        
        public FileDownloadThread(URL url,File file,int startPosition,int endPosition){
            this.url=url;
            this.file=file;
            this.startPosition=startPosition;
            this.curPosition=startPosition;
            this.endPosition=endPosition;
        }
        
        @Override
        public void run() {
            BufferedInputStream bis = null;
            RandomAccessFile fos = null;                                               
            byte[] buf = new byte[BUFFER_SIZE];
            URLConnection con = null;
            try {
                con = url.openConnection();
                con.setAllowUserInteraction(true);
                //设置当前线程下载的起点,终点
                con.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);
                //使用java中的RandomAccessFile 对文件进行随机读写操作
                fos = new RandomAccessFile(file, "rw");
                //设置开始写文件的位置
                fos.seek(startPosition);
                bis = new BufferedInputStream(con.getInputStream());  
                //开始循环以流的形式读写文件
                while (curPosition < endPosition) {
                    int len = bis.read(buf, 0, BUFFER_SIZE);                
                    if (len == -1) {
                        break;
                    }
                    fos.write(buf, 0, len);
                    curPosition = curPosition + len;
                    if (curPosition > endPosition) {
                        downloadSize+=len - (curPosition - endPosition) + 1;
                    } else {
                        downloadSize+=len;
                    }
                }
                //下载完成设为true
                this.finished = true;
                bis.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public boolean isFinished(){
            return finished;
        }
     
        public int getDownloadSize() {
            return downloadSize;
        }
    }
  • 相关阅读:
    table 表格的增删和修改
    js实现单双行文本溢出添加省略号
    C++
    PAT乙级 1029 旧键盘 (C++ python3)
    图论
    图论
    图论
    springcloud(二):注册中心Eureka
    apollo配置中心初探
    Apollo 配置详细步骤(Windows环境)
  • 原文地址:https://www.cnblogs.com/gongcb/p/2755079.html
Copyright © 2011-2022 走看看