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

相关文章

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

JavaScript全屏,监听页面是否全屏

在JavaScript中,直接监听浏览器是否进入全屏模式并不直接支持,因为全屏API主要是关于请求和退出全屏模式的,而没有直接的监听器可以告知页面何时进入或退出全屏模式。但是,你可以通过在你的代码中跟踪全屏状态的改变来模拟这个功能。 以下是一个基本的示例,展示了如何使用全屏API来请求全屏模式,并在请求成功或失败时更新一个状态变量: javascriptlet isInFullscreen =

在服务器上浏览图片

@StarSky 2018-10-26 15:09 字数 15971 阅读 28 https://www.zybuluo.com/StarSky/note/1294871 来源 2018-09-27 线上服务器安装 imgcat Tool   2018-09-27 线上服务器安装 imgcat 0. 准备文件:iterm2_shell_integration.bash1. 在有权限

el-upload 上传图片及回显照片和预览图片,文件流和http线上链接格式操作

<div v-for="(info, index) in zsjzqwhxqList.helicopterTourInfoList" :key="info.id" >编辑上传图片// oss返回线上地址http链接格式:<el-form-itemlabel="巡视结果照片":label-width="formLabelWidth"><el-upload:action="'http:

okhttp3的详细介绍

这篇文章说下OkHttp的基本用法,是最新的3哦,如果你曾经在网上搜索OkHttp怎么使用发现有些类没有了可能是因为人家说的是2。首先说下OkHttp3是Java和Android都能用,Android还有一个著名网络库叫Volley,那个只有Android能用。导入自己到入jar包,别漏了okio:okhttp-3.3.0.jarokio-1.8.0.jarmaven方式:<dependen

SpringBoot中如何监听两个不同源的RabbitMQ消息队列

spring-boot如何配置监听两个不同的RabbitMQ 由于前段时间在公司开发过程中碰到了一个问题,需要同时监听两个不同的rabbitMq,但是之前没有同时监听两个RabbitMq的情况,因此在同事的帮助下,成功实现了监听多个MQ。下面我给大家一步一步讲解下,也为自己做个笔记; 详细步骤: 1. application.properties 文件配置: u.rabbitmq.ad

oracle19c第七步的时候进度卡在了42%

1、oracle 19c安装到第七步的时候进度卡在了42%,好长时间,以为挂了,后来查找资料才知道不是挂了,资料说如果当时以为挂了关闭的话,还得重新安装,幸亏当时没有直接关闭,然后等了有一段时间,然后安装成功了,特此记录一下。

Android 圆圈进度

CircleProgressView 圆圈进度条、中间进度文字(可设置是否显示) 效果 1.圆帽 strokeCapRound=“true” 2.非圆帽子 strokeCapRound=“false” 资源 名字资源AARcircle_progress_view.aarGitHubCircleProgressViewGiteeCircleProgressView Maven 1

【QML】用 Image(QQuickPaintedItem) 显示图片

大体功能: 频繁地往界面推送图片,帧率达到视频效果。捕获画布上的鼠标事件和键盘事件。 代码如下: // DrawImageInQQuickPaintedItem.pro 代码如下:QT += quick# You can make your code fail to compile if it uses deprecated APIs.# In order to do so, uncom

用Ps将PSD切片并将切片保存为透明背景的图片

第一步:选择放大镜工具或者Ctrl++将要切片的部分放大。 第二步:选择移动工具单击要切片的部分,在右边的图层栏找到要切片的图层在文字上右键选择转换为智能对象,再右键该图层的文字选择栅格化图层。 第三步:单击选中所要切片的部分,然后Ctrl+A、Ctrl+C、Ctrl+N(背景内容选择透明)、Ctrl+V、Ctrl+S(将文件保存为PNG格式),这样就可以得到透明背景的图片了!