Android 之多线程下载原理


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

		@Override
		public 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,从服务器获取部分数据,返回:206
				int 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
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值