自我感觉良好的功能

retrofit2+okhttp3下载文件

2019-01-22  本文已影响0人  邻山有木
     没有加Rxjava支持,需要的自行加上即可
    ...别忘了请求权限

代码

    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(Utils.getBaseUrl());

    //下载进度的监听器
    OkHttpClient client = new OkHttpClient.Builder()
            .addNetworkInterceptor(new Interceptor() {

                @Override
                public Response intercept(Chain chain) throws IOException {

                    Response orginalResponse = chain.proceed(chain.request());
                    return orginalResponse.newBuilder()
                            .body(new ProgressResponseBody(orginalResponse.body(), new ProgressListener() {
                                @Override
                                public void onProgress(long progress, long total, boolean done) {

                                    // 计算已下载文件大小的百分比
                                    BigDecimal totalSize = new BigDecimal(((total / 1024f) / 1024f)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal progressSize = new BigDecimal(((progress / 1024f) / 1024f)).setScale(2, BigDecimal.ROUND_HALF_UP);

                                    if (TextUtils.equals(String.valueOf(totalSize), "0.00")) {
                                        SmartToast.show("目标文件为空文件");
                                        return;
                                    }

                                    Log.d(TAG, "onProgress: 共" + totalSize + "MB,已下载" + progressSize + "MB");

                                    if ((int) ((progress * 100) / total) > newProgress) {
                                        newProgress = (int) ((progress * 100) / total);

                                        Message msg = mHandler.obtainMessage();
                                        msg.what = 100;
                                        msg.obj = newProgress;
                                        mHandler.sendMessage(msg);
                                        Log.d(TAG, "onProgress: 下载百分比-->" + newProgress);
                                    }
                                }
                            }))
                            .build();
                }
            })
            .build();


    //加载监听器
    SystemApis download = builder.client(client).build().create(SystemApis.class);
    //开始下载
    download.downloadApk().enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
            //下载完成,此时下载的内容还在body里面,吊桶该方法将body存到SD卡上,返回true则保存成功
            try {
                if (Utils.writeFileToDisk(response.body()))
                    mHandler.sendEmptyMessage(101);
            } catch (Exception e) {
                Log.e(TAG, "onResponse: ", e);
                updateDialog.dismiss();
                SmartToast.show("下载异常,可能服务器并未有该文件存在");
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            // 甩锅大法好
            SmartToast.show("更新失败,网络异常");
        }
    });

这个是Handler

            case 100://正在下载
                int progress = (int) msg.obj;
                updateDialog.setProgress(progress);
                break;

            case 101://下载完成
                updateDialog.dismiss();
                SmartToast.show("下载完成,准备安装");
                Utils.installPackage(LoginActivity.this, Constant.SDCardPath.APKName);
                break;
            case 102://保存失败(或者下载失败)
                updateDialog.dismiss();
                SmartToast.show("遇到未知错误,请重新下载");
                break;

ProcessResponseBody

    import okhttp3.MediaType;
    import okhttp3.ResponseBody;
    import okio.Buffer;
    import okio.BufferedSource;
    import okio.ForwardingSource;
    import okio.Okio;
    import okio.Source;

    /**
    * 重写ResponseBody,实现监听下载进度功能
    * Created by danie on 2017/11/22.
    */
   public class ProgressResponseBody extends ResponseBody {

   private final ResponseBody responseBody;
   private final ProgressListener listener;
   private BufferedSource bufferedSource;

    public ProgressResponseBody(ResponseBody responseBody, ProgressListener listener) {
        this.responseBody = responseBody;
        this.listener = listener;
    }

    @Nullable
    @Override
        public MediaType contentType() {
        return responseBody.contentType();
     }

     @Override
      public long contentLength() {
          return responseBody.contentLength();
      }

    @Override
    public BufferedSource source() {
        if (null == bufferedSource) {
            bufferedSource = Okio.buffer(source(responseBody.source()));
        }
        return bufferedSource;
    }

    private Source source(Source source) {
        return new ForwardingSource(source) {
            long totalBytesRead = 0L;

            @Override
            public long read(Buffer sink, long byteCount) throws IOException {
                l ong bytesRead = super.read(sink, byteCount);
                totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                listener.onProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                return bytesRead;
            }
        };
    }
}

ProgressListener

    /**
     * Retrofit下载文件时下载进度的回调
     * Created by danie on 2017/11/22.
     */
    public interface ProgressListener {
        /**
         * @param progress     已经下载或上传字节数
         * @param total        总字节数
         * @param done         是否完成
         */
        void onProgress(long progress, long total, boolean done);
     }

OJBK,现在才是真的要下班了!

上一篇下一篇

猜你喜欢

热点阅读