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; } }