Android文件下载(实现断点续传)

来源:互联网 发布:阿里云服务器的ip地址 编辑:程序博客网 时间:2024/06/04 17:50
http://www.ideasandroid.com/archives/328#more-328
本文将介绍在android平台下如何实现多线程下载,大家都知道,android平台使用java做为开发语言,所以java中支持的多线程下载方式在android平台下都支持,其中主要有两种方式可以实现多线程下载。

一种方式是使用很多个线程分别下载文件的不同部分,最后把所有下载完的文件合并成一个文件。另一种方式是使用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