本文将介绍在android平台下如何实现多线程下载,大家都知道,android平台使用java做为开发语言,所以java中支持的多线程下载方式在android平台下都支持,其中主要有两种方式可以实现多线程下载。
一种方式是使用很多个线程分别下载文件的不同部分,最后把所有下载完的文件合并成一个文件。另一种方式是使用java为我们提供的RandomAccessFile类实现多线程的下载。
从性能上分析,第二种方式的存取速度会慢一些,但开发起来较为容易,不需要进行合并文件等操作。本文将使用第二种方式来实现多线程下载,最终效果如下图所示:
使用图形界面来获取需要下载的内容,并实时更新下载进度条,代码如下所示:
android多线程断点下载
http://llb988.blog.51cto.com/1940549/510035
Andorid多线程断点续传下载器
http://www.jcodecraeer.com/a/opensource/2015/0602/2978.html
Android 多线程下载 仿下载助手
http://blog.csdn.net/u011733020/article/details/47016715
一种方式是使用很多个线程分别下载文件的不同部分,最后把所有下载完的文件合并成一个文件。另一种方式是使用java为我们提供的RandomAccessFile类实现多线程的下载。
从性能上分析,第二种方式的存取速度会慢一些,但开发起来较为容易,不需要进行合并文件等操作。本文将使用第二种方式来实现多线程下载,最终效果如下图所示:
使用图形界面来获取需要下载的内容,并实时更新下载进度条,代码如下所示:
- import java.io.File;
- import java.net.URL;
- import java.net.URLConnection;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- /**
- * Copyright (C) 2010 ideasandroid
- * 演示android多线程下载
- * 欢迎访问http://www.ideasandroid.com
- * 让程序开发不再那么神秘
- */
- public class FileDownloadDemo extends Activity {
- private EditText downloadUrl;
- private EditText downloadFileName;
- private EditText downloadThreadNum;
- private Button downloadBt;
- private ProgressBar downloadProgressBar;
- private TextView progressMessage;
- private int downloadedSize = 0;
- private int fileSize = 0;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- downloadUrl = (EditText) findViewById(R.id.downloadUrl);
- downloadFileName = (EditText) findViewById(R.id.downloadFileName);
- downloadThreadNum = (EditText) findViewById(R.id.downloadThreadNum);
- progressMessage = (TextView) findViewById(R.id.progressMessage);
- downloadBt = (Button) findViewById(R.id.downloadBt);
- downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);
- downloadProgressBar.setVisibility(View.VISIBLE);
- downloadProgressBar.setMax(100);
- downloadProgressBar.setProgress(0);
- downloadBt.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- download();
- }
- });
- }
- private void download() {
- // 获取SD卡目录
- String dowloadDir = Environment.getExternalStorageDirectory()
- + "/ideasdownload/";
- File file = new File(dowloadDir);
- //创建下载目录
- if (!file.exists()) {
- file.mkdirs();
- }
- //读取下载线程数,如果为空,则单线程下载
- int downloadTN = Integer.valueOf("".equals(downloadThreadNum.getText()
- .toString()) ? "1" : downloadThreadNum.getText().toString());
- //如果下载文件名为空则获取Url尾为文件名
- int fileNameStart = downloadUrl.getText().toString().lastIndexOf("/");
- String fileName = "".equals(downloadFileName.getText().toString()) ? downloadUrl
- .getText().toString().substring(fileNameStart)
- : downloadFileName.getText().toString();
- //开始下载前把下载按钮设置为不可用
- downloadBt.setClickable(false);
- //进度条设为0
- downloadProgressBar.setProgress(0);
- //启动文件下载线程
- new downloadTask(downloadUrl.getText().toString(), Integer
- .valueOf(downloadTN), dowloadDir + fileName).start();
- }
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息
- int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100))).intValue();
- if (progress == 100) {
- downloadBt.setClickable(true);
- progressMessage.setText("下载完成!");
- } else {
- progressMessage.setText("当前进度:" + progress + "%");
- }
- downloadProgressBar.setProgress(progress);
- }
- };
- /**
- * @author ideasandroid
- * 主下载线程
- */
- public class downloadTask extends Thread {
- private int blockSize, downloadSizeMore;
- private int threadNum = 5;
- String urlStr, threadNo, fileName;
- public downloadTask(String urlStr, int threadNum, String fileName) {
- this.urlStr = urlStr;
- this.threadNum = threadNum;
- this.fileName = fileName;
- }
- @Override
- public void run() {
- FileDownloadThread[] fds = new FileDownloadThread[threadNum];
- try {
- URL url = new URL(urlStr);
- URLConnection conn = url.openConnection();
- //获取下载文件的总大小
- fileSize = conn.getContentLength();
- //计算每个线程要下载的数据量
- blockSize = fileSize / threadNum;
- // 解决整除后百分比计算误差
- downloadSizeMore = (fileSize % threadNum);
- File file = new File(fileName);
- for (int i = 0; i < threadNum; i++) {
- //启动线程,分别下载自己需要下载的部分
- FileDownloadThread fdt = new FileDownloadThread(url, file,
- i * blockSize, (i + 1) * blockSize - 1);
- fdt.setName("Thread" + i);
- fdt.start();
- fds[i] = fdt;
- }
- boolean finished = false;
- while (!finished) {
- // 先把整除的余数搞定
- downloadedSize = downloadSizeMore;
- finished = true;
- for (int i = 0; i < fds.length; i++) {
- downloadedSize += fds[i].getDownloadSize();
- if (!fds[i].isFinished()) {
- finished = false;
- }
- }
- //通知handler去更新视图组件
- handler.sendEmptyMessage(0);
- //休息1秒后再读取下载进度
- sleep(1000);
- }
- } catch (Exception e) {
- }
- }
- }
- }
- import java.io.BufferedInputStream;
- import java.io.File;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.net.URL;
- import java.net.URLConnection;
- import android.util.Log;
- /**
- * Copyright (C) 2010 ideasandroid
- * 演示android多线程下载
- * 欢迎访问http://www.ideasandroid.com
- * 让程序开发不再那么神秘
- *
- * 单个下载线程
- */
- public class FileDownloadThread extends Thread{
- private static final int BUFFER_SIZE=1024;
- private URL url;
- private File file;
- private int startPosition;
- private int endPosition;
- private int curPosition;
- //用于标识当前线程是否下载完成
- private boolean finished=false;
- private int downloadSize=0;
- public FileDownloadThread(URL url,File file,int startPosition,int endPosition){
- this.url=url;
- this.file=file;
- this.startPosition=startPosition;
- this.curPosition=startPosition;
- this.endPosition=endPosition;
- }
- @Override
- public void run() {
- BufferedInputStream bis = null;
- RandomAccessFile fos = null;
- byte[] buf = new byte[BUFFER_SIZE];
- URLConnection con = null;
- try {
- con = url.openConnection();
- con.setAllowUserInteraction(true);
- //设置当前线程下载的起点,终点
- con.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition);
- //使用java中的RandomAccessFile 对文件进行随机读写操作
- fos = new RandomAccessFile(file, "rw");
- //设置开始写文件的位置
- fos.seek(startPosition);
- bis = new BufferedInputStream(con.getInputStream());
- //开始循环以流的形式读写文件
- while (curPosition < endPosition) {
- int len = bis.read(buf, 0, BUFFER_SIZE);
- if (len == -1) {
- break;
- }
- fos.write(buf, 0, len);
- curPosition = curPosition + len;
- if (curPosition > endPosition) {
- downloadSize+=len - (curPosition - endPosition) + 1;
- } else {
- downloadSize+=len;
- }
- }
- //下载完成设为true
- this.finished = true;
- bis.close();
- fos.close();
- } catch (IOException e) {
- Log.d(getName() +" Error:", e.getMessage());
- }
- }
- public boolean isFinished(){
- return finished;
- }
- public int getDownloadSize() {
- return downloadSize;
- }
- }
android多线程断点下载
http://llb988.blog.51cto.com/1940549/510035
Andorid多线程断点续传下载器
http://www.jcodecraeer.com/a/opensource/2015/0602/2978.html
Android 多线程下载 仿下载助手
http://blog.csdn.net/u011733020/article/details/47016715