Android开发 retrofit下载与上传
前言
此博客只讲解retrofit下载与上传的使用,其实与其说是retrofit的下载与上传还不如说,依然是Okhttp的下载与上传.如果你需要了解retrofit入门请查看这篇博客(此博客不在详细讲解一些基础的东西):https://www.cnblogs.com/guanxinjing/p/11594249.html
下载
设置下载接口
public interface HttpList {
@Streaming //注解这个请求将获取数据流,此后将不会这些获取的请求数据保存到内存中,将交与你操作.
@GET
Call<ResponseBody> download(@Url String url);
}
这里有一个很重要的东西! @Url属性, 这个属性是你导入的下载地址. 它可以是绝对地址和可以是相对地址,当你使用这个属性的时候,Retrofit设置基础Url的baseUrl("http://p.gdown.baidu.com/") 将自动判断地址是绝对还是相对,从而选择拼接Url还是替换Url !
请求下载
private void downloadFile() {
final File file = new File(getExternalCacheDir(), "demo.apk");
if (file.exists()) {
file.delete();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://p.gdown.baidu.com/")//base的网络地址
.callbackExecutor(Executors.newSingleThreadExecutor())//设置线程,如果不设置下载在读取流的时候就会报错
.build();
HttpList httpList = retrofit.create(HttpList.class);
Call<ResponseBody> call = httpList.download(DOWNLOAD_URL_PATH);//下载地址 太长了所以我用DOWNLOAD_URL_PATH封装了一下,不要误解
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
long total = response.body().contentLength();//需要下载的总大小
long current = 0;
InputStream inputStream = response.body().byteStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, len);
fileOutputStream.flush();
current = current + len;
Log.e(TAG, "已经下载=" + current + " 需要下载=" + total);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
以上的下载实现的关键点,其实是ResponseBody,而这个其实就是okhttp的请求接口后返回的响应body. Retrofit并没有对这个进行封装,所以如果你了解okhttp的使用,应该是轻轻松松的.
上传
上传一般有好几种情况:
- 不需要进度的上传
- 需要进度的上传
- 批量上传
无进度的文件上传
接口服务类
public interface HttpList {
@Multipart
@POST("test/upfile")
Call<ResponseBody> upFile(@Part MultipartBody.Part part);
}
注意这里的Body是 MultipartBody
上传实现
/**
* 无进度上传
*/
private void updateFile(){
final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
if (!imageFile.getParentFile().exists()){
imageFile.getParentFile().mkdirs();
} Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class); //
/*
* "image/jpg" 是你要上传的文件的格式 这个格式并不是固定的,是根据你的项目使用那些何种key也有很多是使用下面这个:
* RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
*/
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), imageFile); //注意这里的file是对应MultipartBody上传文件的key名称
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile); Call<ResponseBody> call = list.upFile(multipartBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: 上传成功 "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
} } @Override
public void onFailure(Call<ResponseBody> call, Throwable t) { }
}); }
有进度的文件上传
/**
* 有进度的上传
*/
private void updateFile(){
final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
if (!imageFile.getParentFile().exists()){
imageFile.getParentFile().mkdirs();
} Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class);
RequestBody requestFile = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse("image/jpg");//这里返回上传的格式 根据项目情况也可以切换成"multipart/form-data" 等等其他格式
} @Override
public void writeTo(BufferedSink sink) throws IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile(imageFile, "rw");
long totalLength = 0;
long currentUpLength = 0;
if (totalLength == 0) {
totalLength = randomAccessFile.length();
}
byte[] bytes = new byte[2048];
int len = 0;
try {
while ((len = randomAccessFile.read(bytes)) != -1) {
sink.write(bytes, 0, len);
currentUpLength = currentUpLength + len;
Log.e(TAG, "writeTo: totalLength="+totalLength + " currentUpLength="+currentUpLength);
}
}catch (Exception e){
Log.e(TAG, "上传中断");
}finally {
randomAccessFile.close();//关闭流
Log.e(TAG, "流关闭");
} }
}; MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile); Call<ResponseBody> call = list.upFile(multipartBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: 上传成功 "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
} } @Override
public void onFailure(Call<ResponseBody> call, Throwable t) { }
}); }
批量上传文件(无对应key的批量上传)
接口服务类
public interface HttpList {
@Multipart
@POST("test/upfileList")
Call<ResponseBody> upFileList(@Part List<MultipartBody.Part> partList);
}
其他与单个上传一致
批量上传文件(有对应key的批量上传)
接口服务类
public interface HttpList {
@Multipart
@POST("test/upfileList")
Call<ResponseBody> upFileList(@PartMap Map<String, RequestBody> map);
}
实现批量上传
private void updateFile3(){
final File imageFile1 = new File(getExternalCacheDir() + "/image/demo_1.jpg");
final File imageFile2 = new File(getExternalCacheDir() + "/image/demo_2.jpg");
final File imageFile3 = new File(getExternalCacheDir() + "/image/demo_3.jpg");
RequestBody requestFile1 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile1);
RequestBody requestFile2 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile2);
RequestBody requestFile3 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile3);
Map<String, RequestBody> map = new HashMap<>();
map.put("file1", requestFile1); //file1 就是需要上传每个文件的key名称
map.put("file2", requestFile2);
map.put("file3", requestFile3);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class);
Call<ResponseBody> call = list.upFileList(map);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//上传成功
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
end
Android开发 retrofit下载与上传的更多相关文章
- Android开发之下载服务器上的一张图片到本地java代码实现HttpURLConnection
package com.david.HttpURLConnectionDemo; import java.io.FileOutputStream; import java.io.IOException ...
- iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充
一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...
- SNF开发平台WinForm之六-上传下载组件使用-SNF快速开发平台3.3-Spring.Net.Framework
6.1运行效果: 6.2开发实现: 1.先在要使用的项目进行引用,SNF.WinForm.Attachments.dll文件. 2.在工具箱内新建选项卡->选择项,浏览找到文件SNF.WinFo ...
- ios开发之网络数据的下载与上传
要实现网络数据的下载与上传,主要有三种方式 > NSURLConnection 针对少量数据,使用“GET”或“POST”方法从服务器获取数据,使用“POST”方法向服务器传输数据; > ...
- iOS开发中文件的上传和下载功能的基本实现-备用
感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...
- Android Http实现文件的上传和下载
最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂.直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了 ...
- iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件
NSURLSession加载数据.下载.上传文件 NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍. 1,使用Data Task加载数据 使用全局的 ...
- 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化
联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...
- Retrofit实现图文上传至服务器
Retrofit实现图文上传至服务器 前言:现在大多数的项目中都涉及图片+文字上传了,下面请详见实现原理: 开发环境:AndroidStudio 1.引入依赖: compile 'com.square ...
随机推荐
- Java8向后兼容
toInstant()方法被添加到可用于将它们转换到新的日期时间的API原始日期和日历对象.使用ofInstant(Insant,ZoneId)方法得到一个LocalDateTime或ZonedDat ...
- CSS中复选框单选框与常用12px文字不对齐问题(转载)
原文 http://www.cnblogs.com/aobingyan/p/3823556.html,有删改 目前中文网站上面的文字,绝大多数网站的主流文字大小为12px,因为在目前高分辨率显示器屏 ...
- JDK8新特性之Optional
Optional是什么 java.util.Optional Jdk8提供Optional,一个可以包含null值的容器对象,可以用来代替xx != null的判断. Optional常用方法 of ...
- java-day24
JDBC控制事务: 1.事务:一个包含多个步骤的业务操作,如果这个业务操作被事务管理,则这个步骤要么同时成功,要么同时失败. 2. 操作: 1. 开启事务 2. 提交事 ...
- python面试题之你如何管理不同版本的代码?
答案: 版本管理!被问到这个问题的时候,你应该要表现得很兴奋,甚至告诉他们你是如何使用Git(或是其他你最喜欢的工具)追踪自己和奶奶的书信往来.我偏向于使用Git作为版本控制系统(VCS),但还有其他 ...
- java堆转储与内存分析
jmap -dump:format=b,file=dumpfile.hprof pid 将进程的堆转储到dumpfile.hprof文件里 jmap -heap pid 查看堆内存占用情 ...
- linux 7下已有mysql之后,如何使用
今天在使用阿里云平台的esc时,选择的centos7系统,在安装mariadb的时候,发现系统已经自带了,然后却无法使用,在调查了之后,发现启动service的依赖件没有安装,所以安装以下依赖件. m ...
- [转]mybatis-generator 代码自动生成工具(maven方式)
由于MyBatis属于一种半自动的ORM框架,所以主要的工作将是书写Mapping映射文件,但是由于手写映射文件很容易出错,mybatis-gennerator插件帮我们自动生成mybatis所需要的 ...
- css制作旋转风车(transform 篇)
做这个案例之前首先要大概了解CSS的transform的属性 transform 属性向元素应用 2D 或 3D 转换.该属性允许我们对元素进行旋转.缩放.移动或倾斜. 看看效果图 打开的时候自动旋转 ...
- NX二次开发-UFUN相加布尔操作,可保留或删除目标体,工具体UF_MODL_unite_bodies_with_retained_options
NX11+VS2013 #include <uf.h> #include <uf_modl.h> UF_initialize(); //创建块 UF_FEATURE_SIGN ...