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

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


android 多线程下载
多线程下载步骤: 1.本地创建一个跟服务器一样的大小一样的文件 临时文件。 2.计算分配几个线程去下载服务器上的资源 每个文件下载的位置。 3.开启线程,每一个线程下载对应的文件。 4.如果所有的线程都把自己的数据下载完成了,服务器上的资源就被下载到本地了
如图所示:(假设有三个线程在进行下载) Android 之多线程下载原理_第1张图片

服务器端: 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,微信等的安装包,自己安装到电脑上,便可以用该方法实现。

更多相关文章

  1. Android Handler 主线程 子线程 双向通信
  2. Android中打包含有Activity以及资源文件的jar包在工程中调用
  3. android 开发零起步学习笔记(九):android 控制控件的位置和大小及L
  4. Android任务、进程、线程详解
  5. Android中使用定制系统的签名文件给应用签名
  6. Android中高效的显示图片之二——在非UI线程中处理图片
  7. Android Studio中新建assets文件的两种方法

随机推荐

  1. Android简明开发教程九:创建应用程序框架
  2. android各个版本的名称和更新
  3. Android的selector背景选择器
  4. Google应用在Android上的Push机制以及C2D
  5. Windows环境下Android(安卓)NDK环境搭建
  6. Android(安卓)am 指令的使用
  7. [Android] 为Android安装BusyBox —— 完
  8. Android使用TextView实现无下划线超链接
  9. 在mac上运行android的intel模拟器导致的
  10. android activity之间传值