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. 数据库服务软件类型和配置redis

                                                        ql-day11     数据库服务软件类型和配置redis   l 数据库服务软件类型 ² R ...

  2. 微信小程序中使用template

    当我们的项目需要多次使用同一个布局和样式的时候,我们就可以考虑使用template(模块)来减少冗余的代码. 使用方法: 1. 新建一个template文件夹存放通用模板: 2. 在文件夹汇里面新建一 ...

  3. 这个案例写出来,还怕跟面试官扯不明白 OAuth2 登录流程?

    昨天和小伙伴们介绍了 OAuth2 的基本概念,在讲解 Spring Cloud Security OAuth2 之前,我还是先来通过实际代码来和小伙伴们把 OAuth2 中的各个授权模式走一遍,今天 ...

  4. Gradle系列之初识Gradle

    原文首发于微信公众号:躬行之(jzman-blog) 学习 Android 有一段时间了,开发中经常使用到 Gradle ,但是不知道 Gradle 构建项目的原理,计划花一点时间学习一下 Gradl ...

  5. 33.2 案例:输出指定目录下的所有java文件名(包含子目录)

    package day32_file_文件和目录操作; import java.io.File; public class test_输出指定目录下所有的java文件名 { public static ...

  6. ZooKeeper 如何保证数据一致性?

    在分布式场景中,ZooKeeper 的应用非常广泛,比如数据发布和订阅.命名服务.配置中心.注册中心.分布式锁等. 在分布式场景中,ZooKeeper 的应用非常广泛,比如数据发布和订阅.命名服务.配 ...

  7. 09-sass

    一.sass和scss sass最初是为了配合haml设计的,不需要大括号,用tab缩进 从第三代开始,保留缩进风格,完全向下兼容普通的css代码 二.下载配置sass compass是sass的一个 ...

  8. Linux常用命令01(文件和目录)

    目标 查看目录内容 ls 切换目录 cd 创建和删除文件 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 > 和 &g ...

  9. 绝地求生模拟登陆!高难度JS解密教程,Python高级爬虫开发,

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取htt ...

  10. Key Set HDU - 5363

    这个题目套公式 2^(n-1)-1,再来个快速幂基本上就可以AC了 写这个题目的: 公式容易推到错: 容易写成 2^n-1/2...这样写出来结果也不错  但是一直哇 AC: #include< ...