android之网络资源多线程下载

package com.example.threaddown;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;

public class MainActivity extends Activity {

	EditText url;
	EditText target;
	Button downBn;
	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);
		downBn = (Button) findViewById(R.id.downBn);
		bar = (ProgressBar) findViewById(R.id.br);
		// 创建一个Handler对象
		final Handler handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 0x123) {
					bar.setProgress(mDownStatus);
				}
			}

		};
		downBn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 初始化DownUtil对象
				downUtil = new DownUtil(url.getText().toString(), target
						.getText().toString(), 6);
				new Thread() {

					@Override
					public void run() {
						try {
							// 开始下载
							downUtil.download();

						} catch (Exception e) {
							e.printStackTrace();
						}
						// 定义每秒调度获取一次系统的完成进度
						final Timer timer = new Timer();
						timer.schedule(new TimerTask() {

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

				}.start();
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}


package com.example.threaddown;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

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.targetFile = targetFile;
		this.threadNum = threadNum;
	}

	public void download() throws IOException {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5000);
		conn.setRequestMethod("GET");
		conn.setRequestProperty("Accept", "*/*");
		conn.setRequestProperty("Accept-Language", "zh-CN");
		conn.setRequestProperty("Charset", "UTF-8");
		conn.setRequestProperty("Connection", "Keep-Alive");
		// 得到文件的大小
		fileSize = conn.getContentLength();
		conn.disconnect();
		int currentPartsSize = fileSize / threadNum + 1;
		RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
		// 设置本地文件的大小
		file.setLength(fileSize);
		file.close();
		for (int i = 0; i < threadNum; i++) {
			// 计算每条线程的下载位置
			int startPos = i * currentPartsSize;
			// 每个线程使用一个RandomAccessFile进行下载
			RandomAccessFile current = new RandomAccessFile(targetFile, "rw");
			// 定义该线程的下载位置
			current.seek(startPos);
			// 创建下载线程
			threads[i] = new DownThread(startPos, currentPartsSize, current);
			// 启动线程下载
			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 currentPartsSize;
		// 当前线程下载的文件块
		private RandomAccessFile currentPart;
		// 定义该线程已下载的字节数
		private int length;

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

		}

		@Override
		public void run() {
			try {
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection) url
						.openConnection();
				conn.setConnectTimeout(5000);
				conn.setRequestMethod("GET");
				conn.setRequestProperty("Accept", "*/*");
				conn.setRequestProperty("Accept-Language", "zh-CN");
				conn.setRequestProperty("Charset", "UTF-8");
				conn.setRequestProperty("Connection", "Keep-Alive");
				InputStream in = conn.getInputStream();
				in.skip(startPos);
				int hasRead = 0;
				byte[] buffer = new byte[1024];
				// 读取网络数据,并写入本地文件
				while (length < currentPartsSize
						&& (hasRead = in.read(buffer)) > 0) {
					currentPart.write(buffer, 0, hasRead);
					// 累计该线程下载的总大小
					length += hasRead;
				}
				currentPart.close();
				in.close();

			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	}

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/url"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="http://ksoap2-android.googlecode.com/svn/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/3.1.0/ksoap2-android-assembly-3.1.0-jar-with-dependencies.jar" />

    <EditText
        android:id="@+id/target"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="/mnt/sdcard/"/>

    <Button
        android:id="@+id/downBn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="down" />

    <ProgressBar
        android:id="@+id/br"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

    <!-- 在SD卡中创建与删除文件的权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 在SD开中写入数据的权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 访问网路的权限 -->
    <uses-permission android:name="android.permission.INTERNET" />


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值