Okhttp、Retrofit进度获取的方法(一行代码搞定)

Okhttp、Retrofit进度获取的方法(一行代码搞定),第1张

概述起因对于广大Android开发者来说,最近用的最多的网络库,莫过于Okhttp啦(Retrofit依赖Okhttp)。

起因

对于广大AndroID开发者来说,最近用的最多的网络库,莫过于Okhttp啦(Retrofit依赖Okhttp)。

Okhttp不像SDK内置的httpUrlConnection一样,可以明确的获取数据读写的过程,我们需要执行一些 *** 作。

介绍

Retrofit依赖Okhttp、Okhttp依赖于Okio。那么Okio又是什么鬼?别急,看官方介绍:
Okio is a library that complements java.io and java.nio to make it much easIEr to access,store,and process your data.

翻译过来就是,Okio是一个实现了java.io和java.nio的一个类库,它让连接,存储,处理你的数据更加轻松~(Okio既是读写相关类库,获取进度要从Okio入手)。

好吧,对于广大开发者来说,内心是这样的:TM又要看你文档和用例,按你规则走,轻松个毛啊!

其实,读下API,看下Example熟悉后,人家设计的还是很棒哒。

废话不多说,先看效果。

效果

实际代码

 //添加下载拦截器(this参数是实现下载进度接口的对象)  mDownClIEnt = new OkhttpClIEnt.Builder()       //只需要一行代码就行了      .addNetworkInterceptor(new DownloadInterceptor(this))      .build();       //添加上传拦截器(this参数是实现上传回调接口的对象)       mUploadClIEnt = new OkhttpClIEnt.Builder()       //只需要一行代码就行了      .addNetworkInterceptor(new UploadInterceptor(this))      .build();

你只需要一行代码是不行的!我为什么行?因为这是我写的封装类库啊~(最后放地址)

思路

Okhttp依赖Okio进行了数据的读写动作,我们需要找到Okio进行处理。那么,如何加上呢?

Okhttp可以添加Interceptor(拦截器),我们可以通过拦截器的接口方法,获取对应的responseBody、requestbody对象进行 *** 作。然后我们就获取了读写相关的实现方法。具体实现是通过Source、Sink对象。

Source官方解释:SupplIEs a stream of bytes. Use this interface to read data from wherever it's located。

Sink官方解释:Receives a stream of bytes. Use this interface to write data wherever it's needed。

一句话概括:Source对象是对输入流的包装(下载读数据),Sink是对输出流的包装(写数据上传)。

实现

根据需要添加下载、上传Interceptor

   //添加下载拦截器(this参数是实现下载进度接口的对象)   mDownClIEnt = new OkhttpClIEnt.Builder()      .addNetworkInterceptor(new DownloadInterceptor(this))      .build();       //添加上传拦截器(this参数是实现上传回调接口的对象)       mUploadClIEnt = new OkhttpClIEnt.Builder()      .addNetworkInterceptor(new UploadInterceptor(this))      .build(); 

拦截器具体实现

 //下载拦截器   public class DownloadInterceptor implements Interceptor {private OnDownloadListener mListener;public DownloadInterceptor( OnDownloadListener Listener) {  mListener = Listener;}@OverrIDepublic Response intercept(Chain chain) throws IOException {  //封装ressponse对象  Response response = wrapResponse(chain.proceed(chain.request()));  return response;}private Response wrapResponse(Response response) {  if (response == null || response.body() == null) {    return response;  }  //获取处理后的response对象  Response wrapResponse = getWrapResponse(response);  return wrapResponse;}private Response getWrapResponse(Response response) {  ProgressInfo info = new ProgressInfo();  info.setTime(System.currentTimeMillis()+"");  info.setUrl(response.request().url().toString());  Response.Builder builder = response.newBuilder();  //封装responseBody,传入相关参数,获取进度数据回调  return builder.body(new WrapResponseBody(response.body(),info,mListener)).build();}}  --------------------------------------分割--------------------------------------- //上传拦截器 public class UploadInterceptor implements Interceptor {private OnUploadListener mListener;public UploadInterceptor(OnUploadListener Listener) {  mListener = Listener;}@OverrIDepublic Response intercept(Chain chain) throws IOException {  //封装request对象  Request request = wrapRequest(chain.request());  Response response = chain.proceed(request);  return response;}private Request wrapRequest(Request request) {  if (request == null || request.body() == null) {    return request;  }  Request.Builder builder = request.newBuilder();  ProgressInfo info = new ProgressInfo();  httpUrl url = request.url();  info.setUrl(url.toString());  info.setTime(System.currentTimeMillis()+"");  //封装requestbody,传入参数,获取数据进度回调  builder.method(request.method(),new WrapRequestbody(request.body(),mListener));  return builder.build();  } }responseBody、requestbody相关实现//继承ResponseBody实现具体方法public class WrapResponseBody extends ResponseBody {private Handler mHandler = new Handler(Looper.getMainLooper());private ResponseBody mResponseBody;private OnDownloadListener mListener;private ProgressInfo mInfo;private BufferedSource mBufferedSource;private boolean mDoProgress;//传入进度,以及监听对象public WrapResponseBody(ResponseBody responseBody,ProgressInfo info,OnDownloadListener Listener) {  mResponseBody = responseBody;  mInfo = info;  mListener = Listener;}@Nullable@OverrIDepublic MediaType ContentType() {  //接口方法,返回类型  return mResponseBody.ContentType();}@OverrIDepublic long contentLength() {    long contentLength = mResponseBody.contentLength();  //Gzip压缩格式会返回-1,目前处理是在请求头信息指定("Accept-EnCoding","IDentity")表示不压缩  if (contentLength == -1) {    mDoProgress = false;    mHandler.post(new Runnable() {      @OverrIDe      public voID run() {        //切换线程,进行失败回调        mListener.onDownLoadGetContentLengthFail(mInfo);      }    });  } else {    mDoProgress = true;  }  return contentLength;}@OverrIDepublic BufferedSource source() {  //WrapSource(继承ForwardingSource,ForwardingSource实现了Source接口)  if (mBufferedSource == null) {    mInfo.setContentLength(contentLength());     //传入参数,读取具体进度信息,并回调     WrapSource wrapSource = new WrapSource(mResponseBody.source(),mInfo,mListener,mDoProgress);    mBufferedSource = Okio.buffer(wrapSource);  }  return mBufferedSource;}}--------------------------------------分割---------------------------------------  //继承Resquestbody实现具体方法public class WrapRequestbody extends Requestbody {private Requestbody mRequestbody;private OnUploadListener mListener;private ProgressInfo mInfo;private boolean mDoProgress;private Handler mHandler = new Handler(Looper.getMainLooper()); //传入进度,以及监听对象public WrapRequestbody(Requestbody requestbody,OnUploadListener Listener) {  mRequestbody = requestbody;  mListener = Listener;  mInfo = info;}@OverrIDepublic MediaType ContentType() {  //接口方法,返回类型  return mRequestbody.ContentType();}@OverrIDepublic long contentLength() throws IOException {  try {    //上传内容长度,有异常走failWrok处理    long l = mRequestbody.contentLength();    mDoProgress = true;    return l;  } catch (IOException e) {    e.printstacktrace();    failWork();    return -1;  }}//进行失败处理private voID failWork() {  mDoProgress = false;  mHandler.post(new Runnable() {    @OverrIDe    public voID run() {      //切换线程,回调失败信息      mListener.onUploadGetContentLengthFail(mInfo);    }  });}@OverrIDepublic voID writeto(BufferedSink sink) throws IOException {  mInfo.setContentLength(contentLength());  // WrapSink (继承ForwardingSink,ForwardingSink实现了Sink接口)  ///传入参数,读取具体进度信息,并回调   WrapSink wrapSink = new WrapSink(sink,mDoProgress);  BufferedSink buffer = Okio.buffer(wrapSink);  mRequestbody.writeto(buffer);  buffer.flush();}}WrapSource、WrapSink相关实现//继承ForwardingSource 实现具体方法public class WrapSource extends ForwardingSource {private Handler mHandler = new Handler(Looper.getMainLooper());private Source mSource;private ProgressInfo mInfo;private OnDownloadListener mListener;private boolean mDoProgress;public WrapSource(Source source,OnDownloadListener Listener,boolean doProgress) {  //传入源Source、进度信息、监听进度等信息。  super(source);  mSource = source;  mInfo = info;  mListener = Listener;  //传入是否继续执行回调boolean参数,如果之前执行有异常,则不再继续执行回调  mDoProgress = doProgress;}@OverrIDepublic long read(Buffer sink,long byteCount) throws IOException {  //获取具体进度信息,来到了熟悉的具体IO  long read = super.read(sink,byteCount);  if (read != -1) {    long l = mInfo.getCurrentLength() + read;    mInfo.setCurrentLength(l);    mHandler.post(new Runnable() {      @OverrIDe      public voID run() {        if (mDoProgress) {          //切换到主线程,回调数据          mListener.onDownLoadProgress(mInfo);        }      }    });  }  return read;}}--------------------------------------分割---------------------------------------//继承ForwardingSink 实现具体方法public class WrapSink extends ForwardingSink {private Handler mHandler = new Handler(Looper.getMainLooper());public OnUploadListener mListener;public ProgressInfo mInfo;public boolean mDoProgress;public WrapSink(Sink delegate,OnUploadListener Listener,boolean doProgress) {  //传入源Source、进度信息、监听进度等信息。  super(delegate);  mInfo = info;  mListener = Listener;   //传入是否继续执行回调boolean参数,如果之前执行有异常,则不再继续执行回调  mDoProgress = doProgress;}@OverrIDepublic voID write(Buffer source,long byteCount) throws IOException {  super.write(source,byteCount);  //获取具体进度信息,来到了熟悉的具体IO  long l = mInfo.getCurrentLength() + byteCount;  mInfo.setCurrentLength(l);  mHandler.post(new Runnable() {    @OverrIDe    public voID run() {      if (mDoProgress) {        //切换到主线程,回调数据        mListener.onUpLoadProgress(mInfo);      }    }  });}}

总结

以上就是具体的流程了,按照步骤其实很简单。大家了解下挺好的,我这边也封装好了具体的类库和Demo,大家可以直接依赖(查看README.md,使用简单)。

地址:https://github.com/HoldMyOwn/TNetProgress

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:Retrofit+Rxjava下载文件进度的实现Android Retrofit文件下载进度显示问题的解决方法Android中实现OkHttp上传文件到服务器并带进度android中实现OkHttp下载文件并带进度条android使用OkHttp实现下载的进度监听和断点续传详解Android使用OKHttp3实现下载(断点续传、显示进度)Android okhttputils现在进度显示实例代码 总结

以上是内存溢出为你收集整理的Okhttp、Retrofit进度获取的方法(一行代码搞定)全部内容,希望文章能够帮你解决Okhttp、Retrofit进度获取的方法(一行代码搞定)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1142858.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存