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的文件上传和进度提示的更多相关文章

  1. .Net neatupload上传控件实现文件上传的进度条

    1. 引入bin文件 (可以到neatupload官网下载,也可以到教育厅申报系统中找) 2. 将控件加入到工具栏,在工具栏中点鼠标右键,如图: 3. 加入neatuplaod这个文件夹(可以到nea ...

  2. 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 ...

  3. 使用Typescript重构axios(二十五)——文件上传下载进度监控

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  4. atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7

    atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7 1. 实现原理 1 2. 大的文件上传原理::使用applet 1 3. 新的bp 2 1. 性能提升---分割小文件上传 ...

  5. vue+element UI + axios封装文件上传及进度条组件

    1.前言 之前在做项目的时候,需要实现一个文件上传组件并且需要有文件上传进度条,现将之前的实现过程简单记录一下,希望可以帮助到有需要的人. 项目用的是Vue框架,UI库使用的是element UI,前 ...

  6. springMVC+ajax 文件上传 带进度条

    前端代码: <form id= "uploadForm"> <p >指定文件名: <input type="text" name= ...

  7. html5拖拽事件 xhr2 实现文件上传 含进度条

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. .net网站的文件上传读取进度条和断点下载

    文件上传到服务器时的进度读取 //调整上传配置 AdapterInfo(info); UpfileResult result = new UpfileResult(); try { //直接使用req ...

  9. Flex4/Flash多文件上传(带进度条)实例分享

    要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演 ...

随机推荐

  1. Mysql数据库卸载

    Mysql数据库卸载的操作流程(Windows10): 1.停止mysql的所有服务 方法一:此电脑——管理——服务中查找到所有Mysql的服务,并停止. 方法二:cmd——net stop mysq ...

  2. 详细解析 HBASE 配置的各种要点

    文章更新于:2020-04-06 安装惯例,需要的文件附上链接放在文首. 文件名:hbase-2.2.4-bin.tar.gz 文件大小:213.24 MB 下载链接:http://download. ...

  3. flask-宏

    flask-宏 模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量,使用宏的时候,参数可以为默认值. ...

  4. C++11中的四种类型转换

    static_cast 基础数据类型转换(基本类型) 同一继承体系中类型的转换(父子类型) 任意类型与空指针(void *)之间的转换(指针类型) dynamic_cast 执行派生类指针或引用与基类 ...

  5. Linq中带有迭代索引的Select扩展方法,为啥知道的人不多呢?

    一:背景 昨天在看C#函数式编程这本书的时候,有一处让我干着急,需求是这样: 给多行文字加上数字列表项. 针对这个需求你会如何快捷高效的给每个项目加上数字编号呢? 我看书中是这样实现的,如下代码 pu ...

  6. sigmod函数求导

    sigmod函数: \[f(z)=\frac{1}{1+e^{-z}} \] 求导: \[\frac{\partial f(z)}{\partial z}=\frac{-1*-1*e^{-z}}{(1 ...

  7. thinkphp5.0远程执行漏洞

    0x01 漏洞简介 由于ThinkPHP5 框架控制器名 没有进行足够的安全监测,导致在没有开启强制路由的情况下,可以伪装特定的请求可以直接Getshell(可以控制服务器) 0x02 环境搭建 Ph ...

  8. AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据

    AJ分享,必须精品 一:效果 没有图文混排,也没有复杂的UI,仅仅是简单的显示出微博数据,主要介绍AFNetworking和SDWebImage的简单用法 二:加载数据AFNetworking AFN ...

  9. App 开发中判断 ios 和 andriod 常用方法便于修复在两类机型样式不一样等缺陷

    判断安卓, ios

  10. python机器学习入门-(1)

    机器学习入门项目 如果你和我一样是一个机器学习小白,这里我将会带你进行一个简单项目带你入门机器学习.开始吧! 1.项目介绍 这个项目是针对鸢尾花进行分类,数据集是含鸢尾花的三个亚属的分类信息,通过机器 ...