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. .NET Core项目部署到Linux(Centos7)(十)总结

    目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...

  2. 【Linux】系统管理

    软件包管理 一 软件包分类 源码包: .tar.gz .tar.bz2 二进制包: .rpm 二 二进制包安装 (一) rpm命令手动管理二进制包 (挂载光盘) 1 包名-版本号-发布次数-适合lin ...

  3. 【php】日期时间

    一. 日期时间: a) 这是一块非常重要的内容,我们在windows当中,或者是将来要接触的定时器也好,都是需要使用到这一块内容的!二. PHP当中的日期时间: a) 时间戳:time()可以获取时间 ...

  4. 使用ping命令探测系统

    什么是ping命令 ping命令是测试网络连接.信息发送和接收状况的实用型工具,是系统内置的探测性工具.它的原理是:每台网络上的主机都有唯一确定的IP地址,用户给目标IP发送一个数据报,对方就要返回一 ...

  5. linux美化网址

    参考博文地址 https://blog.csdn.net/qq_42527676/article/details/91356154 https://www.opendesktop.org/ Dash ...

  6. Android 圆形图片库 CircleImageView

    高仿微信朋友圈 10s 视频裁剪 引语 晚上好,我是猫咪,我的公众号「程序媛猫咪」会推荐 GitHub 上好玩的项目,挖掘开源的价值,欢迎关注我. <Android 图片裁剪库 uCrop> ...

  7. C#两大知名Redis客户端连接哨兵集群的姿势

    前言 前面利用<Docker-Compose搭建Redis高可用哨兵集群>, 我们的思路是将Redis.Sentinel.Redis Client App链接到同一个网桥网络,这个网桥内的 ...

  8. python3(四)list tuple

    # !/usr/bin/env python3 # -*- coding: utf-8 -*- # list是一种有序的集合,可以随时添加和删除其中的元素. classmates = ['Michae ...

  9. hadoop(三)伪分布模式hdfs文件处理|5

    伪分布模式hdfs 1.启动hsfs 2. 编辑vi hadoop-env.sh image.png image.png 3.配置nameNode和生产文件第地址 [shaozhiqi@hadoop1 ...

  10. 11-Json提取器使用

    1.使用json提取关键信息 有时候接口返回数据为json数据或者直接为一个列表,可使用这个更简单快捷 json数据: 这样的,数据有在result里面以列表形式存在,也有在列表外的,可在json提取 ...