Android断点续传原理及实现

16 篇文章 1 订阅
5 篇文章 1 订阅

常见两种网络请求方式

一、 HttpURLConnection

HttpURLConnection的setRequestProperty()方法,对我们要读取的字节部分进行控制,比如:
···
1.Range=0-100代表只读取前100个字节。
2.Range=100-500代表读取从第100个字节开始,读到第500个字节为止。
3.Range=100-则代表从第100个字节开始读取,一直读取到文件末尾结束。

···
断点续传过程
1、在暂停时记录一下已经读取到的位置,在重新开始的时候利用setRequestProperty()方法设置一下我们要读取的字节位置即可
2、RandomAccessFile来进行字节流的写入,RandomAccessFile有一个方法seek(long),允许我们指定要写入的位置

多线程断点续传实现原理相同,只是利用多个线程同时下载,每个线程指定要下载的字节部分,写入到文件的指定部分

二、 okhttp

1、调用请求获取文件长度
2、先判断文件是否找到,找到代表已经下载过,则获取其长度 判断长度是否大于文件长度 大于则创建新文件继续下载或者下载终止
3、设置请求头请求范围

//确定下载的范围,添加此头,则服务器就可以跳过已经下载好的部分  
                    .addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength) 

4、存储时候设置:RandomAccessFile这个类,但是如果不涉及到多个部分拼接的话是没必要的,直接使用输出流就好了,在输出流的构造方法上添加一个true的参数,代表是在原文件的后面添加数据即可

三 、 httpurlconnection 示例
class SingleDownloadTask{

        private String filePath;
        private int contentLength;
        private int readLength;
        private RandomAccessFile file=null;
         private boolean isPause=false;
        private URL url;

         public boolean isDownloading() {
             return isDownloading;
         }

         private boolean isDownloading=false;

        private Handler mHandler=new Handler();

        public SingleDownloadTask(String urlStr,String filePath) {
            this.filePath=filePath;
            readLength=0;
            contentLength=0;
            try {
                url=new URL(urlStr);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

        //download from pos
        public void download(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    isDownloading=true;
                    HttpURLConnection conn=null;
                    InputStream is=null;
                    BufferedInputStream bis=null;
                    try {
                        file=new RandomAccessFile(filePath,"rw");
                        file.seek(readLength);
                        conn= (HttpURLConnection) url.openConnection();
                        if(readLength==0){
                            contentLength=conn.getContentLength();
                        }else{
                            conn.setRequestProperty("Range","bytes="+readLength+"-");
                        }
                        is=conn.getInputStream();
                        bis=new BufferedInputStream(is);
                        byte[] bytes=new byte[1024];
                        int len=0;
                        while (!isPause&&((len=bis.read(bytes,0,1024)))!=-1){
                            file.write(bytes,0,len);
                            readLength+=len;
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    float rate=((float)readLength)/contentLength;
                                    mProgressBar.setProgress((int) (100*rate));
                                    mTextView.setText((int)(100*rate)+"%");
                                }
                            });
                        }
                        isDownloading=false;
                        if (readLength>=contentLength){
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, "文件下载成功,保存在"+filePath
                                            , Toast.LENGTH_SHORT).show();
                                    mImageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
                                }
                            });
                        }
                        file.close();
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        if (bis!=null){
                            try {
                                bis.close();
                                if (is!=null){
                                    is.close();
                                }
                                if (conn!=null){
                                    conn.disconnect();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }).start();
        }

        public void start(){
            isPause=false;
            download();
        }

        public void pause(){
            isPause=true;
        }

    }

四、 okhttp示例

https://www.jianshu.com/p/fe3607dddacc

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值