前言

  此博客只讲解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下载与上传的更多相关文章

  1. Android开发之下载服务器上的一张图片到本地java代码实现HttpURLConnection

    package com.david.HttpURLConnectionDemo; import java.io.FileOutputStream; import java.io.IOException ...

  2. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

  3. SNF开发平台WinForm之六-上传下载组件使用-SNF快速开发平台3.3-Spring.Net.Framework

    6.1运行效果: 6.2开发实现: 1.先在要使用的项目进行引用,SNF.WinForm.Attachments.dll文件. 2.在工具箱内新建选项卡->选择项,浏览找到文件SNF.WinFo ...

  4. ios开发之网络数据的下载与上传

    要实现网络数据的下载与上传,主要有三种方式 > NSURLConnection  针对少量数据,使用“GET”或“POST”方法从服务器获取数据,使用“POST”方法向服务器传输数据; > ...

  5. iOS开发中文件的上传和下载功能的基本实现-备用

    感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...

  6. Android Http实现文件的上传和下载

    最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂.直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了 ...

  7. iOS开发——网络Swift篇&NSURLSession加载数据、下载、上传文件

    NSURLSession加载数据.下载.上传文件   NSURLSession类支持三种类型的任务:加载数据.下载和上传.下面通过样例分别进行介绍.   1,使用Data Task加载数据 使用全局的 ...

  8. 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化

    联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...

  9. Retrofit实现图文上传至服务器

    Retrofit实现图文上传至服务器 前言:现在大多数的项目中都涉及图片+文字上传了,下面请详见实现原理: 开发环境:AndroidStudio 1.引入依赖: compile 'com.square ...

随机推荐

  1. Node篇

    [Node篇] Node.js中的stream(流)- 基础篇 1)什么是stream(流) 流(stream)在 Node.js 中是处理流数据的抽象接口(abstract interface). ...

  2. Neo4j:Index索引

    Indexing in Neo4j: An Overview by Stefan Armbruster · Jan. 06, 14 · Java Zone Neo4j是一个图数据库,在做图的检索时,用 ...

  3. 笔记44 Hibernate快速入门(一)

    一.Hibernate简介 Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象. Hibernate 架构是分层的,作为数据访问层,你不 ...

  4. pandas-append()

    DataFrame.append(self,other,ignore_index = False,verify_integrity = False,sort = Nore) 作用是将其他对象附加到调用 ...

  5. python 编写暴力破解mysql用户名密码

    本文摘自别人的,自己运行调试了一下#!/user/bin/env python#-*- coding:utf-8 -*- import pymysql#导入连接数据库的模块import sys cla ...

  6. Centos6.5 安装 LAMP

    Centos 安装 LAMP 系统: Centos 6.5 Apache 2.4 + PHP 7.2 + Mysql 5.7 准备工作 centos 查看版本 查看 centos版本 How to C ...

  7. Spring Boot 2.X 对 web 的开发支持(二)

    Spring Boot 2.X 对 web 的支持开发 上章节的 Spring Boot 的入门案例,我们感受到 Spring Boot 简单的配置即可运行项目. 今天了解 Spring Boot 对 ...

  8. struts2-convention-plugin零配置

    零配置的意思并不是说没有配置,而是通过约定大于配置的方式,大量通过约定来调度页面的跳转而使得配置大大减少. <?xml version="1.0" encoding=&quo ...

  9. js简单图片切换

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title> ...

  10. tomcat部署安全证书文件(阿里云SSL证书)

    1.下载安全证书文件: 这里使用的是阿里云SSL证书(免费一年) 2.把下载的压缩包进行解压 3.将pfx文件拷贝至服务器 4.利用jdk将pfx转jks 5.cmd进入命令行 6.切换至jdk的bi ...