Android---53---多线程下载

使用HttpURLConnection

HttpURLConnection继承自URLConnection,也可用于向指定的网站发送GET请求

POST请求。

方法:

int getResponseCode ():

获取服务器的响应代码

String getResponseMessage ():

获取服务器的响应消息

String getResponseMethod ():

获取发送请求的方法

void setRequestMethod ():

设置发送请求的方法

多线程下载

步骤:

1.创建URL对象

2.获取指定URL对象所指向资源的大小 由getContentLength()实现

3.在本地磁盘上创建一个与网络资源相同大小的空文件

4.计算每条线程应该下载网络资源的那个部分(从哪个字节开始,到哪个字节结束)

5.依次创建、启动多条线程来下载网络资源的指定部分。

下载工具类:

public class DownUtil
{
	// 定义下载资源的路径
	private String path;
	// 指定所下载的文件的保存位置
	private String targetFile;
	// 定义需要使用多少线程下载资源
	private int threadNum;
	// 定义下载的线程对象
	private DownThread[] threads;
	// 定义下载的文件的总大小
	private int fileSize;

	public DownUtil(String path, String targetFile, int threadNum)
	{
		this.path = path;
		this.threadNum = threadNum;
		// 初始化threads数组
		threads = new DownThread[threadNum];
		this.targetFile = targetFile;
	}

	public void download() throws Exception
	{
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5 * 1000);
		conn.setRequestMethod("GET");
		conn.setRequestProperty(
			"Accept",
			"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
			+ "application/x-shockwave-flash, application/xaml+xml, "
			+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
			+ "application/x-ms-application, application/vnd.ms-excel, "
			+ "application/vnd.ms-powerpoint, application/msword, */*");
		conn.setRequestProperty("Accept-Language", "zh-CN");
		conn.setRequestProperty("Charset", "UTF-8");
		conn.setRequestProperty("Connection", "Keep-Alive");
		// 得到文件大小
		fileSize = conn.getContentLength();
		conn.disconnect();
		int currentPartSize = fileSize / threadNum + 1;
		RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
		// 设置本地文件的大小
		file.setLength(fileSize);
		file.close();
		for (int i = 0; i < threadNum; i++)
		{
			// 计算每条线程的下载的开始位置
			int startPos = i * currentPartSize;
			// 每个线程使用一个RandomAccessFile进行下载
			RandomAccessFile currentPart = new RandomAccessFile(targetFile,
				"rw");
			// 定位该线程的下载位置
			currentPart.seek(startPos);
			// 创建下载线程
			threads[i] = new DownThread(startPos, currentPartSize,
				currentPart);
			// 启动下载线程
			threads[i].start();
		}
	}

	// 获取下载的完成百分比
	public double getCompleteRate()
	{
		// 统计多条线程已经下载的总大小
		int sumSize = 0;
		for (int i = 0; i < threadNum; i++)
		{
			sumSize += threads[i].length;
		}
		// 返回已经完成的百分比
		return sumSize * 1.0 / fileSize;
	}

	private class DownThread extends Thread
	{
		// 当前线程的下载位置
		private int startPos;
		// 定义当前线程负责下载的文件大小
		private int currentPartSize;
		// 当前线程需要下载的文件块
		private RandomAccessFile currentPart;
		// 定义已经该线程已下载的字节数
		public int length;

		public DownThread(int startPos, int currentPartSize,
			RandomAccessFile currentPart)
		{
			this.startPos = startPos;
			this.currentPartSize = currentPartSize;
			this.currentPart = currentPart;
		}

		@Override
		public void run()
		{
			try
			{
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection)url
					.openConnection();
				conn.setConnectTimeout(5 * 1000);
				conn.setRequestMethod("GET");
				conn.setRequestProperty(
					"Accept",
					"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
					+ "application/x-shockwave-flash, application/xaml+xml, "
					+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
					+ "application/x-ms-application, application/vnd.ms-excel, "
					+ "application/vnd.ms-powerpoint, application/msword, */*");
				conn.setRequestProperty("Accept-Language", "zh-CN");
				conn.setRequestProperty("Charset", "UTF-8");
				InputStream inStream = conn.getInputStream();
				// 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
				inStream.skip(this.startPos);
				byte[] buffer = new byte[1024];
				int hasRead = 0;
				// 读取网络数据,并写入本地文件
				while (length < currentPartSize
					&& (hasRead = inStream.read(buffer)) > 0)
				{
					currentPart.write(buffer, 0, hasRead);
					// 累计该线程下载的总大小
					length += hasRead;
				}
				currentPart.close();
				inStream.close();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}

Activity:

public class MainActivity extends Activity {

	EditText url;
	EditText target;
	Button downButton;
	ProgressBar bar;
	DownUtil downUtil;

	private int mDownStatus;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		url = (EditText) findViewById(R.id.url);
		target = (EditText) findViewById(R.id.target);
		downButton = (Button) findViewById(R.id.down);
		bar = (ProgressBar) findViewById(R.id.bar);

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 0x123) {
					bar.setProgress(mDownStatus);
				}
			}
		};
		downButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				downUtil = new DownUtil(url.getText().toString(), target
						.getText().toString(), 6);
				new Thread() {
					public void run() {
						try {
							downUtil.download();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

						final Timer timer = new Timer();
						timer.schedule(new TimerTask() {

							@Override
							public void run() {
								// 获取下载任务的完成比率
								double completeRate = downUtil
										.getCompleteRate();
								mDownStatus = (int) (completeRate * 100);
								// 发送消息通知界面更新进度条
								handler.sendEmptyMessage(0x123);
								// 下载完全后取消任务调度
								if (mDownStatus >= 100) {
									timer.cancel();
								}

							}
						}, 0, 100);

					};

				}.start();
			}
		});
	}
}
时间: 2024-11-15 00:50:48

Android---53---多线程下载的相关文章

Android版多线程下载器核心代码分享

首先给大家分享多线程下载核心类: 1 package com.example.urltest; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.RandomAccessFile; 6 import java.net.HttpURLConnection; 7 import java.net.MalformedURLException; 8 import java.net.URL; 9 im

Android 模拟多线程下载

以下是一个多线程下载的例子,见代码: 1.首先是布局文件 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height

Android中多线程下载列表的封装实现(含进度反馈)

来源:http://blog.csdn.net/u011638883/article/details/17347015 实现了一下Android中的文件多线程下载模块,支持自定义线程数.断点续传.下载任务的删除,添加等功能,这里封装了一下,功能已全部实现.不过由于使用的是最简单的手动线程数组及消息通知实现,可能还存在某些小问题.笔者会在后面的使用过程中再进行优化完善.先看一下程序测试效果,这里指定了5个下载任务,以及2个下载线程,具体如下: 要运行以上Demo需要自己搭建服务器,和简单,只需要把

Android之——多线程下载示例(一)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46883927 一.概述 说到Android中的文件下载,Android API中明确要求将耗时的操作放到一个子线程中执行,文件的下载无疑是需要耗费时间的,所以要将文件的下载放到子线程中执行.下面,我们一起来实现一个Android中利用多线程下载文件的小例子. 二.服务端准备 在这个小例子中我以下载有道词典为例,在网上下载有道词典的安装包,在eclipse中新建项目web,将下载的

Android 之多线程下载原理

在Android之中呢,对于多线程的操作很是平凡,所以对于多线程的理解越深,那么对于自己的程序便能够很好的运行 这也是对于Android开发是一个重要的知识点,那么我们现在来了解多线程的下载原理. android 多线程下载 多线程下载步骤: 1.本地创建一个跟服务器一样的大小一样的文件 临时文件. 2.计算分配几个线程去下载服务器上的资源 每个文件下载的位置. 3.开启线程,每一个线程下载对应的文件. 4.如果所有的线程都把自己的数据下载完成了,服务器上的资源就被下载到本地了 如图所示:(假设

Android之——多线程下载演示样例

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46883927 一.概述 说到Android中的文件下载.Android API中明白要求将耗时的操作放到一个子线程中运行,文件的下载无疑是须要耗费时间的.所以要将文件的下载放到子线程中运行. 以下,我们一起来实现一个Android中利用多线程下载文件的小样例. 二.服务端准备 在这个小样例中我下面载有道词典为例.在网上下载有道词典的安装包,在eclipse中新建项目web.将下载

Android开发--多线程下载加断点续传

文件下载在App应用中也用到很多,一般版本更新时多要用的文件下载来进行处理,以前也有看过很多大神有过该方面的博客,今天我也自己来实践一下,写的一般,还请大家多提意见,共同进步.主要思路: 1.多线程下载: 首先通过下载总线程数来划分文件的下载区域:利用int range = fileSize / threadCount:得到每一段下载量:每一段的位置是i * range到(i + 1) * rang  - 1,注意最后一段的位置是到filesize - 1: 通过Http协议的Range字段实现

Android中 多线程下载原理

计算每个线程的下载起始终止位置公式如下 文件读写方式4中类型 工程源码目录 package cn.itcast.download; import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class MulThreadDownloader { public stat

android程序----&gt;android多线程下载(二)

上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序---->android多线程下载(一) 目录导航 android中多线程下载的思路 android中多线程中的原理说明 android中多线程下载的实现 友情链接 android中多线程下载的思路 一. 多线程下载的步骤说明: 第一步: 我们要获得下载资源的的长度,用http请求中HttpURLConn

android开发笔记之多线程下载及断点续传

今天我们来接触一下多线程下载,当然也包括断点续传,我们可以看到 很多下载器,当开通会员的时候下载东西的速度就变得快了许多,这是为什么呢?这就是跟今天讲的多线程有关系了,其实就是多开了几个线程一起下载罢了.当然真正的多线程下载要比这个复杂,要考虑很多问题. 做个不恰当的比喻: 假如我们把一个服务器上的文件看作是一个水缸里的水的话,那么多线程下载就相当于从水缸上打了多个小孔,然后塞进去小管道进行抽水.呵呵,也许这个比喻不够准确. 效果: 这里下载的是本地服务器上的文件,你们可以下载网络上的一些文件.