retrofit2+okhttp3图片上传及进度监听

2023-12-07 13:48

本文主要是介绍retrofit2+okhttp3图片上传及进度监听,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、使用jar包

由于retrofit2与1的写法有很大的变化,并且对okhttp存在着依赖。所以需要确定选择使用方向,以免陷入不必要的坑中。

本篇讲采用retrofit2 + okhttp3做结合使用。在导包过程中本人也遇到了一些不兼容的麻烦,再此做记录。

retrofit-2.1.0.jar、okhttp-3.4.1.jar、okio-1.6.0.jar、converter-gson-2.1.0.jar

另外我们服务端使用springmvc框架,通过@responseBody返回。前期引入gson包为gson-2.4.jar总报错不知何故,最后换成gson-2.7.jar就可以了。

2、使用retrofit

retrofit使用是有一定规律性,我们可以将其归纳后提出,封装一个针对retrofit的制造者。

public class RetrofitBuilder{private static Retrofit retrofit;public synchronized static Retrofit buildRetrofit(String url){if(retrofit == null){OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure(true).build();retrofit = new Retrofit.Builder.client(client).baseUrl(url).addConverterFactory((GsonConverterFactory.create())).build();}return retrofit;}
}
retrofit对应请求接口

public interface FileuploadService{/***@param parts*@param map(请求参数)*@return(JsonRetrun实体类)*/@Multipart@POST("uploader")Call<JsonReturn> uploadFilesWithParts(@Part() List<MultipartBody.Part> parts , @QueryMap Map<String , String> map);/***@param body*@param map(请求参数)*@return(JsonRetrun实体类)*/@Multipart@POST("uploader")Call<JsonReturn> uploadFilesWithBody(@Body() MultipartBody body , @QueryMap Map<String , String> map);
}
回执泛型实体类
public class JsonReturn{private String errcode;private String errmsg;private String msg;private Object object;set/get方法.....
}
接口中Multipart参数生成,可以封装一个创造者。

public class MultipartBuiler{public static MultipartBody filesToBody(List<File> files , RetrofitCallback<JsonReturn> callback){for(File file : files){RequestBody requestBody = RequestBody.create(MediaType.parse("img/png"),file);FileRequestBody body = new FileRequestBody(reqeustBody , callback , file);builder.addFormDataPart("file" , file.getName , body);}builder.setType(MultipartBody.FORM);MultipartBody multipartBody = builder.build();return multipartBody;}public staitc List<MultipartBody.Part> filesToParts(List<File> files , RetrofitCallback<JsonReturn> callback){List<MultipartBody.Part> parts = new ArrayList<>(files.size());for(File file : files){RequestBody requestBody = RequestBody.create(MediaType.parse("img/png"),file);FileRequestBody body = new FileRequestBody(reqeustBody , callback , file);MultipartBody.Part part = MultipartBody.Part.createFormData("file" , file.getName() , body);parts.add(part);}return parts;}
}
以上可以实现文件的上传了。

3、有的时候我们在项目中需要监听文件的上传进度,那要如何实现呢。继续往下看思路。

上传的过程,我们可以考虑为request的交互过程,所以我们完全可以针对okhttp中的requestBody做些扩展。

/*** 扩展Okhttp的请求体, 实现上传时的进度监听* @author xuximing** @param <T>*/
public class FileRequestBody<T> extends RequestBody {/*** 实体请求体*/private RequestBody requestBody;/*** 上传回调接口*/private RetrofitCallback<T> callback;/*** 文件*/private File file ;/*** 包装完成的BufferedSink*/private BufferedSink bufferedSink;public FileRequestBody(RequestBody requestBody , RetrofitCallback<T> callback , File file){super();this.requestBody = requestBody;this.callback = callback;this.file = file;}@Overridepublic long contentLength() throws IOException {return requestBody.contentLength();}@Overridepublic MediaType contentType() {return requestBody.contentType();}@Overridepublic void writeTo(BufferedSink sink) throws IOException {if(bufferedSink == null){//包装bufferedSink = Okio.buffer(sink(sink));}//写入requestBody.writeTo(bufferedSink);//必须调用flush,否则最后一部分数据可能不会被写入bufferedSink.flush();}/*** 写入,回调进度接口* @param sink* @return*/private Sink sink(Sink sink){return new ForwardingSink(sink) {//当前写入字节数long bytesWritten = 0L;//总字节长度,避免多次调用contentLength()方法long contentLength = 0L;@Overridepublic void write(Buffer source, long byteCount) throws IOException {super.write(source, byteCount);if(contentLength == 0){//获得contentLength的值,后续不再调用contentLength = contentLength();}//增加当前写入的字节数bytesWritten += byteCount;//回调callback.onLoading(file , contentLength, bytesWritten);}};}
}
retrofit中callback不能完全满足我们的需求,我们也可以进一步扩展

public abstract class RetrofitCallback<T> implements Callback<T>{@Overridepublic void onResponse(Call<T> call, Response<T> response) {if(response.isSuccessful()){onSuccess(call, response);}else{onFailure(call, new Throwable(response.message()));}}public abstract void onSuccess(Call<T> call , Response<T> response);public void onLoading(File file , long total , long progress){}
}

4、最终使用

使用起来用到的代码依旧相同,那我们在次提取封装

public class UploadFileUitl{public UploadFileUitl(String url , Map<> paramMap , List mList , RetrofitCallBack callback){List<MultipartBody.Part> parts = MultipartBuilder.filesToParts(mList , callback);//创建Multipart//创建Retrofit,并调用enqueue实现异步操作RetrofitBuilder.buildRetrofit(url).create(FileUploadService.class)'.uploadFilesWithParts(parts , paramMap).enqueue(callback);}
}

ok,开始最终的调用吧

new UploadFileUtil(url , paramMap , fileList , new RetrofitCallback(){//成功@Overridepublic void onSuccess(Call call , Response response){}//失败@Overridepublic void onFailure(Call call , Throwable t){}//加载中@Overridepublic void onLoading(File file , long total , long progress){}
});

不要忘记android的规则,对一些耗时操作不要放在主线程中。因此我们还需要将最终调用放到子线程中。我用的是AsyncTask

class UploadTask extends AsyncTask<Map , Map , Object>{//在执行过程中调用上传监听过程@Overrideprotected Object doInBackground(Map... params){new UploadFileUtil(url , paramMap , fileList , new RetrofitCallback(){//成功@Overridepublic void onSuccess(Call call , Response response){}//失败@Overridepublic void onFailure(Call call , Throwable t){}//加载中@Overridepublic void onLoading(File file , long total , long progress){....publishProgress(map);//出发处理进度}});}//处理进度@Overrideprotected void onProgressUpdate(Map... maps){}
}




 


这篇关于retrofit2+okhttp3图片上传及进度监听的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/466111

相关文章

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python如何去除图片干扰代码示例

《Python如何去除图片干扰代码示例》图片降噪是一个广泛应用于图像处理的技术,可以提高图像质量和相关应用的效果,:本文主要介绍Python如何去除图片干扰的相关资料,文中通过代码介绍的非常详细,... 目录一、噪声去除1. 高斯噪声(像素值正态分布扰动)2. 椒盐噪声(随机黑白像素点)3. 复杂噪声(如伪

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O