Android文件下载(多线程下载同一文件)

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

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

从性能上分析,第二种方式的存取速度会慢一些,但开发起来较为容易,不需要进行合并文件等操作。本文将使用第二种方式来实现多线程下载,最终效果如下图所示: 

 

使用图形界面来获取需要下载的内容,并实时更新下载进度条,代码如下所示: 
Java代码  
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;  
 
public class FileDownloadDemo extends Activity { 
   
    private EditTextdownloadUrl;  
    private EditTextdownloadFileName;  
    private EditTextdownloadThreadNum;  
    private ButtondownloadBt;  
    private ProgressBardownloadProgressBar;  
    private TextViewprogressMessage;  
    private intdownloadedSize = 0;  
    private int fileSize =0;  
   
    @Override 
    public voidonCreate(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(newOnClickListener() {  
            publicvoid onClick(View v) {  
                download(); 
           
        });  
   
   
    private void download(){  
        // 获取SD卡目录  
        String dowloadDir =Environment.getExternalStorageDirect ory()  
                + "/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); 
        //启动文件下载线程  
        newdownloadTask(downloadUrl.getText().toString(), Integer 
                .valueOf(downloadTN),dowloadDir + fileName).start();  
   
   
    Handler handler = newHandler() {  
        @Override  
        public void handleMessage(Message msg) { 
            //当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息  
            intprogress = (Double.valueOf((downloadedSize * 1.0 / fileSize *100))).intValue();  
            if(progress == 100) {  
                downloadBt.setClickable(true);  
                progressMessage.setText("下载完成!");  
            } else { 
                progressMessage.setText("当前进度:" + progress + "%"); 
           
            downloadProgressBar.setProgress(progress);  
        }  
   
    }; 
   
     
    public classdownloadTask extends Thread {  
        private int blockSize, downloadSizeMore; 
        private int threadNum = 5; 
        String urlStr, threadNo, fileName; 
   
        public downloadTask(String urlStr, intthreadNum, 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 = newFile(fileName);  
                for (int i = 0; i< threadNum; i++) {  
                    //启动线程,分别下载自己需要下载的部分  
                    FileDownloadThread fdt = newFileDownloadThread(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) {  
   
           
   
        }  
   
}  

Java代码  
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;  
 
public class FileDownloadThread extends Thread{ 
    private static final intBUFFER_SIZE=1024;  
    private URL url; 
    private File file; 
    private intstartPosition;  
    private int endPosition; 
    private int curPosition; 
    //用于标识当前线程是否下载完成 
    private booleanfinished=false;  
    private intdownloadSize=0;  
    publicFileDownloadThread(URL url,File file,int startPosition,intendPosition){  
        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 = newRandomAccessFile(file, "rw");  
            //设置开始写文件的位置  
            fos.seek(startPosition);  
            bis = newBufferedInputStream(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 booleanisFinished(){  
        return finished;  
   
   
    public intgetDownloadSize() {  
        return downloadSize;  
   
}  


android多线程断点下载 
http://llb988.blog.51cto.com/1940549/510035 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值