多线程下载及XUtils框架使用

一、多线程下载

1、获取文件大小

/**
	 * 获取要下载的文件大小
	 * @param urlStr
	 * @return
	 */
	public static long getFileLength(String urlStr) {
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(10 * 1000);
			conn.setReadTimeout(6 * 1000);

			conn.connect();
			int code = conn.getResponseCode();
			if (code == 200) {
				//获取下载内容的大小,单位是byte
				long contentLength = conn.getContentLength();
				conn.disconnect();
				return contentLength;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return 0;
	}

2、主函数

private static int threadCount = 3; //下载的线程数量
	private static long blockSize; //下载的文件平分每一块的大小

	public static void main(String[] args) {
		new Thread() {
			public void run() {
				//1,获取要下载的文件大小
				String urlStr = "http://192.168.0.145//Content/App/DBX_140614_V2.0.apk";
				long length = getFileLength(urlStr);
				blockSize = length / threadCount;
				try {
					//2,本地创建一个空文件,文件大小和将下载的文件大小一样
					File file = new File("D:\\test.apk");
					//使用RandomAccessFile对象来创建。
					//"rw"为可读写权限,当做多线程断点续传功能是,权限要改为"rwd",目的是能将中断在硬件缓冲区的数据强刷进硬盘。
					RandomAccessFile raf = new RandomAccessFile(file, "rw");
					raf.setLength(length);
				} catch (Exception e) {
					e.printStackTrace();
				}
				//3,开启多个线程
				for (int i = 0; i < threadCount; i++) {
					//计算每个线程下载的开始位置和结束位置
					long startPosition = i * blockSize;
					long endPosition = (i + 1) * blockSize - 1;
					if (i == threadCount - 1) {
						endPosition = length - 1;
					}
					GetDataRunnable getDataRunnable = new GetDataRunnable(
							urlStr, i, startPosition, endPosition);
					Thread thread = new Thread(getDataRunnable);
					thread.start();
				}
			};
		}.start();
	}

3、每个子线程分别下载对应的内容

private static class GetDataRunnable implements Runnable {
		private int id;
		private long startPosition;
		private long endPosition;
		private String urlStr;

		public GetDataRunnable(String urlStr, int id, long startPosition,
				long endPosition) {
			this.id = id;
			this.startPosition = startPosition;
			this.endPosition = endPosition;
			this.urlStr = urlStr;
		}

		@Override
		public void run() {
			HttpURLConnection conn = null;
			RandomAccessFile raf = null;
			InputStream is = null;
			try {
				URL url = new URL(urlStr);
				conn = (HttpURLConnection) url.openConnection();
				conn.setRequestMethod("GET");
				//设置该线程下载内容的范围
				conn.setRequestProperty("Range", "bytes=" + startPosition + "-"
						+ endPosition);
				conn.setConnectTimeout(10 * 1000);
				conn.setReadTimeout(6 * 1000);

				conn.connect();
				File file = new File("D:\\test.apk");
				raf = new RandomAccessFile(file, "rw");
				//把文件的位置指针定位在开始位置
				raf.seek(startPosition);
				//conn.getResponseCode() 成功返回码不是200
				is = conn.getInputStream();
				int len = -1;
				byte[] b = new byte[1024];
				while ((len = is.read(b)) != -1) {
					//往RandomAccessFile指向的本地文件中写入数据
					raf.write(b, 0, len);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (raf != null) {
					try {
						raf.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}

	}

二、Xutils框架的HttpUtils类使用

HttpUtils httpUtils = new HttpUtils();
		httpUtils.download(
				"http://192.168.0.145//Content/App/DBX_140614_V2.0.apk",
				Environment.getExternalStorageDirectory().getAbsolutePath() + "/XX.zip", true,
				true, new RequestCallBack() {

					@Override
					public void onFailure(HttpException arg0, String arg1) {
						Log.i("DBXStore", "onFailure:" + arg1);
					}   

					@Override
					public void onSuccess(ResponseInfo arg0) {
						Log.i("DBXStore", "onSuccess");
					}
				});

三、断点续传

断点续传功能其实就是在上面的多线程功能的基础上,增加一个下载字节的保存。每一个while循环都保存一下当前已下载的字节数。以便暂停后继续进行。

你可能感兴趣的:(Android,多线程下载,Xutils)