Retrofit的文件上传和进度提示
1.写一个上传监听的接口:
/**
* Created by Zzm丶Fiona on 2017/7/31.
*/ public interface RetrofitProgressUploadListener {
/**
*
* @param bytesWriting 已经写的字节数
* @param totalBytes 文件的总字节数
*/
void onProgress(long bytesWriting, long totalBytes);
}
2.重新写一个类继承于RequesBody:
package zzm.zzmotherthingsshouldknowfortheinterview.upload_progress; import android.support.annotation.Nullable; import java.io.IOException; import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink; /**
* Created by Zzm丶Fiona on 2017/7/31.
*/ public class ProgressRequestBody extends RequestBody {
private final RetrofitProgressUploadListener retrofitProgressUploadListener;
private final RequestBody requestBody;
private BufferedSink bufferedSink; public ProgressRequestBody(RetrofitProgressUploadListener retrofitProgressUploadListener, RequestBody requestBody) {
this.retrofitProgressUploadListener = retrofitProgressUploadListener;
this.requestBody = requestBody;
} @Nullable
@Override
public MediaType contentType() {
return requestBody.contentType();
} @Override
public long contentLength() throws IOException {
return requestBody.contentLength();
} //关键方法
@Override
public void writeTo(BufferedSink sink) throws IOException {
if (null == bufferedSink) bufferedSink = Okio.buffer(sink(sink));
requestBody.writeTo(bufferedSink);
//必须调用flush,否则最后一部分数据可能不会被写入
bufferedSink.flush();
} private Sink sink(Sink sink) {
return new ForwardingSink(sink) {
long bytesWriting = 0l;
long contentLength = 0l; @Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if (0 == contentLength) contentLength = contentLength();
bytesWriting += byteCount;
//调用接口,把上传文件的进度传过去
retrofitProgressUploadListener.onProgress(bytesWriting, contentLength);
}
};
}
}
3.封装的方法,返回ProgressRequestBody:
package zzm.zzmotherthingsshouldknowfortheinterview.utils; import android.os.Handler;
import okhttp3.RequestBody;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.ProgressRequestBody;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.RetrofitProgressUploadListener;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.UploadProgressBean; /**
* Created by Zzm丶Fiona on 2017/7/31.
*/ public class RetrofitUploadProgressUtil {
//handler把数据传送到主线程中去处理,展示
public static ProgressRequestBody getProgressRequesBody(RequestBody requestBody, final Handler handler) {
return new ProgressRequestBody(new RetrofitProgressUploadListener() {
UploadProgressBean uploadProgressBean = new UploadProgressBean(); @Override
public void onProgress(long bytesWriting, long totalBytes) {
if (null == uploadProgressBean) uploadProgressBean = new UploadProgressBean();
uploadProgressBean.setBytesWriting(bytesWriting);
uploadProgressBean.setTotalBytes(totalBytes);
handler.sendMessage(handler.obtainMessage(2, uploadProgressBean));
}
}, requestBody);
}
}
4.把自己的写的类继承于RequesBody的ProgressRequestBody传进上传的表单中即可:
/**
* Created by Zzm丶Fiona on 2017/7/30.
*/ public class UploadThingsByRetrofitActivity extends AppCompatActivity { @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),你的上传文件-file);
ProgressRequestBody progressRequestBody = RetrofitUploadProgressUtil.getProgressRequesBody(requestBody, new Handler() {
@Override
public void handleMessage(Message msg) {
//进度的展示:
super.handleMessage(msg);
Log.i("zzmzzm", "已读的字节数: " + ((UploadProgressBean) msg.obj).getTotalBytes());
Log.i("zzmzzm", "上传的文件的字节总数: " + ((UploadProgressBean) msg.obj).getTotalBytes());
}
});
UploadThingsByRetrofitInterface uploadThingsByRetrofitInterface = getUploadThingsInterface();
Call<ResponseBody> upload = uploadThingsByRetrofitInterface.uploadThings(MultipartBody.Part.createFormData(你的key,文件名,progressRequestBody));
upload.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//求情成功的返回
try {
Log.i("zzmzzm", response.body().string());
} catch (IOException e) {
Log.i("zzmzzm", e.toString());
}
}
//求情失败的返回
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.i("zzmzzm", t.toString());
}
}); } private UploadThingsByRetrofitInterface getUploadThingsInterface() {
return new Retrofit.Builder()
.baseUrl("地址")
.build()
.create(UploadThingsByRetrofitInterface.class);
}
}
其中的注解接口:
/**
* Created by Zzm丶Fiona on 2017/7/30.
*/ public interface UploadThingsByRetrofitInterface {
@Multipart
@POST
Call<ResponseBody> uploadThings(@Part MultipartBody.Part uplodThings); }
补充说明:
MediaType.parse(String contentType)中参数contentType常见的有:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
text/x-markdown: markdown文档
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式 以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式) 另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式 另外的可以参考:http://www.w3school.com.cn/media/media_mimeref.asp
转载于:https://my.oschina.net/u/2987490/blog/1492353
Retrofit的文件上传和进度提示的更多相关文章
- .Net neatupload上传控件实现文件上传的进度条
1. 引入bin文件 (可以到neatupload官网下载,也可以到教育厅申报系统中找) 2. 将控件加入到工具栏,在工具栏中点鼠标右键,如图: 3. 加入neatuplaod这个文件夹(可以到nea ...
- atitit. 文件上传带进度条 atiUP 设计 java c# php
atitit. 文件上传带进度条 atiUP 设计 java c# php 1. 设计要求 1 2. 原理and 架构 1 3. ui 2 4. spring mvc 2 5. springMVC.x ...
- 使用Typescript重构axios(二十五)——文件上传下载进度监控
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7
atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7 1. 实现原理 1 2. 大的文件上传原理::使用applet 1 3. 新的bp 2 1. 性能提升---分割小文件上传 ...
- vue+element UI + axios封装文件上传及进度条组件
1.前言 之前在做项目的时候,需要实现一个文件上传组件并且需要有文件上传进度条,现将之前的实现过程简单记录一下,希望可以帮助到有需要的人. 项目用的是Vue框架,UI库使用的是element UI,前 ...
- springMVC+ajax 文件上传 带进度条
前端代码: <form id= "uploadForm"> <p >指定文件名: <input type="text" name= ...
- html5拖拽事件 xhr2 实现文件上传 含进度条
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- .net网站的文件上传读取进度条和断点下载
文件上传到服务器时的进度读取 //调整上传配置 AdapterInfo(info); UpfileResult result = new UpfileResult(); try { //直接使用req ...
- Flex4/Flash多文件上传(带进度条)实例分享
要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演 ...
随机推荐
- 本地Vue项目跨域请求本地Node.js服务器的配置方法
前言:跨域请求是在本地开发时经常遇到的需求,也很简单,只是几句代码配置一下的问题.我初次配置跨域请求时由于官方的说明太简洁,找到的教程又落伍,调试了一番并没有解决问题,到最后解决问题,已花费了很多时间 ...
- 【数据库】MySQL数据库(四)
一.对数据的操作(详细版) 1.添加数据 1> insert into 表名 (字段1,字段2...) values (值1,值2...); 2> insert into 表名 (字段1, ...
- MyBatis(六):SqlSession执行源码分析
SqlSession执行源码分析 针对以下代码 public class MybatisUtils { private static SqlSessionFactory sqlSessionFacto ...
- 给listview添加长时间点击事件(完成删除操作)
出现的问题是:当长时间点击listview的时候,触发长时间点击事件的同时也会触发点击事件,处理的办法是在长时间点击事件中加上return true:这样就可以很好的解决了. 给listview天机长 ...
- flask from_object和from_pyfile的区别
flask from_object和from_pyfile的区别 from_object接受的是一个模块对象,需求导入 from_pyfile接受的是一个文件名的字符串,文件可以不是py文件也可以是 ...
- 利用xposed hook Auto.js程序、解密其js脚本
一.原理 原理很简单就是hook auto.js的com.stardust.autojs.script.StringScriptSource类,当然前题你要逆向的auto.js程序dex没有加固,当然 ...
- Python爬虫系列(七):提高解析效率
如果仅仅因为想要查找文档中的<a>标签而将整片文档进行解析,实在是浪费内存和时间.最快的方法是从一开始就把<a>标签以外的东西都忽略掉. SoupStrainer 类可以定义文 ...
- typename 关键字
1.class关键字的同义词 template <typename T> const T& max(const T& x, const T& y) { return ...
- 02-css3之2D转换
一.CSS3 -2D转换 转换(transform)可以实现元素的位移.旋转.缩放等效果.可以理解为变形. 1. 2D转换之移动translate 可以改变元素的页面中的位置,类似于定位. 1.1语法 ...
- [译]谈谈SpringBoot 事件机制
要"监听"事件,我们总是可以将"监听器"作为事件源中的另一个方法写入事件,但这将使事件源与监听器的逻辑紧密耦合. 对于实际事件,我们比直接方法调用更灵活.我们可 ...
