Retrofit+Rxjava +flatMap操作符 实现单个文件下载功能并回调下载进度

废话不多说直接上代码

ApiService部分 

package com.dawn.httplib.retrofit.function;

import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

public interface APIService {
    @Streaming
    @GET
    Observable<Response<ResponseBody>> doDownload(@Url String Url);
}
 
 

下载信息的实体类 主要用来保存下载文件总大小和当前下载大小

package com.dawn.httplib.download;


public class DownloadInfo {
    public long totalSize;//下载文件总大小
    public long currentSize;//当前下载大小
}

 
 

调用的部分,其中retrofit的初始化没有什么特别之处就不贴出来了

public RetrofitManager sendDownloadRequest(String downloadUrl) {
    retrofit.create(APIService.class)
            .doDownload(downloadUrl)
            //使用flatMap对获取的Response进行转换,转换成带有DownloadInfo的新的Observable也就是ObservableSource<DownloadInfo>
            .flatMap(new Function<Response<ResponseBody>, ObservableSource<DownloadInfo>>() {
                @Override
                public ObservableSource<DownloadInfo> apply(Response<ResponseBody> response) throws Exception {
                    return DownloadHandler.downloadFile(response);//下载的处理
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<DownloadInfo>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(DownloadInfo value) {
                    Log.e("dowanload","===下载进度==totalSize==>"+value.totalSize+"==currentSize==>"+value.currentSize);

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
    return this;
}


其中下载的处理DownloadHandler类

package com.dawn.httplib.handler;


import android.os.Environment;

import com.dawn.httplib.download.DownloadInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import okhttp3.ResponseBody;
import retrofit2.Response;

/**
 * 处理下载
 */

public class DownloadHandler {

    public static Observable<DownloadInfo> downloadFile(final Response<ResponseBody> response) {
        return  Observable.create(new ObservableOnSubscribe<DownloadInfo>() {
            @Override
          public void subscribe(ObservableEmitter<DownloadInfo> ee) throws Exception{
                InputStream is = null;
                FileOutputStream fos = null;
                DownloadInfo downloadInfo=new DownloadInfo();
                try {
                    //这里文件操作记得加权限管理
                    File parenFile = new File(Environment.getExternalStorageDirectory()+ File.separator+"test");//下载的文件夹地址
                    if (!parenFile.exists()) {
                        parenFile.mkdirs();
                    }
                    final File file = new File(parenFile, "test.apk");//下载的文件名称
                    if (file.exists()) {
                        file.delete();
                    }
                    byte[] buf = new byte[2048];
                    int len;
                    long total = response.body().contentLength();
                    long current = 0;
                    is = response.body().byteStream();
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        current += len;
                        fos.write(buf, 0, len);
                        downloadInfo.totalSize=total;
                        downloadInfo.currentSize=current;
                        ee.onNext(downloadInfo);//进度回调
                    }
                    fos.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                    ee.onError(e);//错误回调
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    
}

猜你喜欢

转载自blog.csdn.net/w_1220577523/article/details/79297801