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;
    }
}
posted @ 2012-11-05 14:26  暗殇  阅读(317)  评论(0编辑  收藏  举报