Android文件下载(实现断点续传) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    本文将介绍在android平台下如何实现多线程下载,大家都知道,android平台使用java做为开发语言,所以java中支持的多线程下载方式在android平台下都支持,其中主要有两种方式可以实现多线程下载,

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

    一种方式是使用很多个线程分别下载文件的不同部分,最后把所有下载完的文件合并成一个文件。另一种方式是使用java为我们提供的RandomAccessFile类实现多线程的下载。

    从性能上分析,第二种方式的存取速度会慢一些,但开发起来较为容易,不需要进行合并文件等操作。

    使用图形界面来获取需要下载的内容,并实时更新下载进度条,代码如下所示:

    Java代码

    packagecom.fly.test;

    importandroid.app.Activity;

    importjava.io.File;

    importjava.net.URL;

    importjava.net.URLConnection;

    importcom.fly.thread.FileDownloadThread;

    importandroid.os.Bundle;

    importandroid.os.Environment;

    importandroid.os.Handler;

    importandroid.os.Message;

    importandroid.view.View;

    importandroid.view.View.OnClickListener;

    importandroid.widget.Button;

    importandroid.widget.EditText;

    importandroid.widget.ProgressBar;

    importandroid.widget.TextView;

    /**

    *Copyright (C) 2010ideasandroid

    *演示android多线程下载

    *欢迎访问http://www.ideasandroid.com

    *让程序开发不再那么神秘

    */

    publicclassFileDownloadDemoextendsActivity{

    privateEditTextdownloadUrl;

    privateEditTextdownloadFileName;

    privateEditTextdownloadThreadNum;

    privateButtondownloadBt;

    privateProgressBardownloadProgressBar;

    privateTextViewprogressMessage;

    privateintdownloadedSize=0;

    privateintfileSize=0;

    @Override

    publicvoidonCreate(BundlesavedInstanceState){

    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(newOnClickListener() {

    publicvoidonClick(Viewv) {

    download();

    }

    });

    }

    privatevoiddownload(){

    //获取SD卡目录

    StringdowloadDir=Environment.getExternalStorageDirectory()

    +"/ideasdownload/";

    Filefile=newFile(dowloadDir);

    //创建下载目录

    if(!file.exists()) {

    file.mkdirs();

    }

    //读取下载线程数,如果为空,则单线程下载

    intdownloadTN=Integer.valueOf("".equals(downloadThreadNum.getText()

    .toString())?"1":downloadThreadNum.getText().toString());

    //如果下载文件名为空则获取Url尾为文件名

    intfileNameStart=downloadUrl.getText().toString().lastIndexOf("/");

    StringfileName="".equals(downloadFileName.getText().toString())?downloadUrl

    .getText().toString().substring(fileNameStart)

    :downloadFileName.getText().toString();

    //开始下载前把下载按钮设置为不可用

    downloadBt.setClickable(false);

    //进度条设为0

    downloadProgressBar.setProgress(0);

    //启动文件下载线程

    newdownloadTask(downloadUrll.getText().toString(),Integer

    .valueOf(downloadTN),dowloadDir+fileName).start();

    }

    Handlerhandler=newHandler() {

    @Override

    publicvoidhandleMessage(Messagemsg) {

    //当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息

    intprogress=(Double.valueOf((downloadedSize*1.0/fileSize*100))).intValue();

    if(progress==100) {

    downloadBt.setClickable(true);

    progressMessage.setText("下载完成!");

    }else{

    progressMessage.setText("当前进度:"+progress+"%");

    }

    downloadProgressBar.setProgress(progress);

    }

    };

    /**

    *@authorideasandroid

    *主下载线程

    */

    publicclassdownloadTaskextendsThread{

    privateintblockSize,downloadSizeMore;

    privateintthreadNum=5;

    StringurlStr,threadNo,fileName;

    publicdownloadTask(StringurlStr,intthreadNum,StringfileName) {

    this.urlStr=urlStr;

    this.threadNum=threadNum;

    this.fileName=fileName;

    }

    @Override

    publicvoidrun(){

    FileDownloadThread[]fds=newFileDownloadThread[threadNum];

    try{

    URLurl=newURL(urlStr);

    URLConnectionconn=url.openConnection();

    //获取下载文件的总大小

    fileSize=conn.getContentLength();

    //计算每个线程要下载的数据量

    blockSize=fileSize/threadNum;

    //解决整除后百分比计算误差

    downloadSizeMore=(fileSize%threadNum);

    Filefile=newFile(fileName);

    for(inti=0;i){

    //启动线程,分别下载自己需要下载的部分

    FileDownloadThreadfdt=newFileDownloadThread(url,file,

    i*blockSize,(i+1)*blockSize-1);

    fdt.setName("Thread"+i);

    fdt.start();

    fds[i]=fdt;

    }

    booleanfinished=false;

    while(!finished) {

    //先把整除的余数搞定

    downloadedSize=downloadSizeMore;

    finished=true;

    for(inti=0;i){

    downloadedSize+=fds[i].getDownloadSize();

    if(!fds[i].isFinished()){

    finished=false;

    }

    }

    //通知handler去更新视图组件

    handler.sendEmptyMessage(0);

    //休息1秒后再读取下载进度

    sleep(1000);

    }

    }catch(Exceptione) {

    }

    }

    }

    }

    Java代码

    =================================================================

    importjava.io.BufferedInputStream;

    importjava.io.File;

    importjava.io.IOException;

    importjava.io.RandomAccessFile;

    importjava.net.URL;

    importjava.net.URLConnection;

    importandroid.util.Log;

    /**

    * Copyright (C) 2010ideasandroid

    *演示android多线程下载

    *让程序开发不再那么神秘

    *

    *单个下载线程

    */

    publicclassFileDownloadThreadextendsThread{

    privatestaticfinalintBUFFER_SIZE=1024;

    privateURLurl;

    privateFilefile;

    privateintstartPosition;

    privateintendPosition;

    privateintcurPosition;

    //用于标识当前线程是否下载完成

    privatebooleanfinished=false;

    privateintdownloadSize=0;

    publicFileDownloadThread(URLurl,Filefile,intstartPosition,intendPosition){

    this.url=url;

    this.file=file;

    this.startPosition=startPosition;

    this.curPosition=startPosition;

    this.endPosition=endPosition;

    }

    @Override

    publicvoidrun(){

    BufferedInputStreambis=null;

    RandomAccessFilefos=null;

    byte[]buf=newbyte[BUFFER_SIZE];

    URLConnectioncon=null;

    try{

    con=url.openConnection();

    con.setAllowUserInteraction(true);

    //设置当前线程下载的起点,终点

    con.setRequestProperty("Range","bytes="+startPosition+"-"+endPosition);

    //使用java中的RandomAccessFile对文件进行随机读写操作

    fos=newRandomAccessFile(file,"rw");

    //设置开始写文件的位置

    fos.seek(startPosition);

    bis=newBufferedInputStream(con.getInputStream());

    //开始循环以流的形式读写文件

    while(curPosition) {

    intlen=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(IOExceptione) {

    Log.d(getName()+" Error:",e.getMessage());

    }

    }

    publicbooleanisFinished(){

    returnfinished;

    }

    publicintgetDownloadSize(){

    returndownloadSize;

    }

    }

最新文章