Android 之多线程下载原理

来源:互联网 发布:vasco软件下载 编辑:程序博客网 时间:2024/05/22 00:37


在Android之中呢,对于多线程的操作很是平凡,所以对于多线程的理解越深,那么对于自己的程序便能够很好的运行

这也是对于Android开发是一个重要的知识点,那么我们现在来了解多线程的下载原理。


android 多线程下载

多线程下载步骤:
1.本地创建一个跟服务器一样的大小一样的文件 临时文件。
2.计算分配几个线程去下载服务器上的资源 每个文件下载的位置。
3.开启线程,每一个线程下载对应的文件。
4.如果所有的线程都把自己的数据下载完成了,服务器上的资源就被下载到本地了

如图所示:(假设有三个线程在进行下载)


服务器端:
0   1  2  3  4  5  6   7  8  9

1.文件的长度/3,得到每个线程下载文件的长度。(假设有三个线程进行下载)
线程1:下载 0-2
线程2:下载 3-5
线程3:下载 6-到文件末尾

每一个文件下载的位置计算方式
开始位置:
(线程id - 1) * 每一个快的大小
结束位置: 
(线程id)* 每一快的大小 - 1

下面,我们先用java代码来实现一下
package com.zengtao.tools;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class DemoLoader {private static DemoLoader loader = new DemoLoader();private static int threadCount = 3;private DemoLoader() {}// 单例设计模式public static DemoLoader getInstance() {return loader;}public void downFile(String path) {// 去服务器端获取文件的长度,在本地创建一个跟服务器一样大小的文件try {URL url = new URL(path);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setDoInput(true);connection.setRequestMethod("GET");connection.setReadTimeout(5000);int code = connection.getResponseCode();if (code == 200) {// 获取服务器端文件的长度int fileLength = connection.getContentLength();// 本地创建一个跟服务器一样大小的文件RandomAccessFile raf = new RandomAccessFile("setup.ext", "rwd");raf.setLength(fileLength);raf.close();// 假设三个线程下载int blockSize = fileLength / threadCount;for (int threadId = 0; threadId < threadCount; threadId++) {int startIndex = (threadId - 1) * blockSize;int endIndex = threadId * blockSize - 1;if (threadId == threadCount) {endIndex = fileLength;}System.out.println("线程:" + threadId + ",下载:" + startIndex+ "--->" + endIndex);// 开始下载new DownLoadThread(threadId, startIndex, endIndex, path).start();}System.out.println("文件总长度为:" + fileLength);} else {System.out.println("请求失败!");}} catch (Exception e) {e.printStackTrace();}}/** * 下载文件的主线程 *  * @author Administrator zengtao *  */public class DownLoadThread extends Thread {private int threadId;private int startIndex;private int endIndex;private String path;/** *  * @param threadId *            线程id * @param startIndex *            线程下载开始位置 * @param endIndex *            线程下载结束位置 * @param path *            线程下载结束文件放置地址 */public DownLoadThread(int threadId, int startIndex, int endIndex,String path) {super();this.threadId = threadId;this.startIndex = startIndex;this.endIndex = endIndex;this.path = path;}@Overridepublic void run() {super.run();URL url;try {url = new URL(path);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 请求服务器下载部分的文件,制定开始的位置,和结束位置connection.setRequestProperty("Range", "bytes=" + startIndex+ "-" + endIndex);connection.setDoInput(true);connection.setRequestMethod("GET");connection.setReadTimeout(5000);// 从服务器获取的全部数据,返回:200,从服务器获取部分数据,返回:206int code = connection.getResponseCode();System.out.println("code = " + code);InputStream is = connection.getInputStream();RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");// 随机写文件的时候,从什么时候开始raf.seek(startIndex);int len = 0;byte[] buff = new byte[1024];while ((len = is.read(buff)) != -1) {raf.write(buff, 0, len);}is.close();raf.close();System.out.println("线程:" + threadId + ",下载完成");} catch (Exception e) {e.printStackTrace();}}}}





要使用该类的时候,只需要知道一个url地址,然后调用里面的downFile()方法,就会开始下载文件了,这样实现可以下载一个安装包,比如:在网上下载一个qq,微信等的安装包,自己安装到电脑上,便可以用该方法实现。

0 0
原创粉丝点击