前言

  此博客只讲解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. MySQL数据库(三)—— 表相关操作(二)之约束条件、关联关系、复制表

    表相关操作(二)之约束条件.关联关系.复制表 一.约束条件  1.何为约束 除了数据类型以外额外添加的约束 2.约束条件的作用 为了保证数据的合法性,完整性 3.主要的约束条件 NOT NULL # ...

  2. Laravel/php 一些调试技巧

    1. 模型属性不知道哪里修改? 直接覆盖模型的 setAttribute 方法,监测到某一个属性改动的时候,抛一个异常就可以看到堆栈了 use Illuminate\Database\Eloquent ...

  3. Linux初学习之 rm 命令

    现在我们来仔细的学习一下linux的rm命令,这个命令顾名思义(我猜的,嘻嘻,是remove) 命令格式: rm [OPTION]... FILE... Remove (unlink) the FIL ...

  4. extern static和函数

    #include <stdio.h> int sum(int a, int b); int main() { /************************************** ...

  5. .Net平台调用の初识

    前言 工作过程中难免遇到混合编程,现在我们要谈的是C#和c++语言的编程.C#要调用C++的库目前可选主要有两种方式:Com技术和平台调用(P/Invoke).现在我们要谈的是P/Invoke技术. ...

  6. 因kernel too old 而 centos6.8 升级内核

    因为docker运行centos 的时候,报错了,错误为kernel too old .我看了一下是因为os的内核不行了,需要升级下内核. 查看默认版本: uname -r 忘记截图了,内核大概是2. ...

  7. 2019-3-1-win10-uwp-在-VisualStudio-部署失败,找不到-Windows-Phone-可能的原因

    title author date CreateTime categories win10 uwp 在 VisualStudio 部署失败,找不到 Windows Phone 可能的原因 lindex ...

  8. 74HC595点亮8个LED灯

    一.原理介绍 595有两个寄存器,都是8位的,如下所示: 595是串入并出带有锁存功能移位寄存器,它的使用方法简单: - -  在正常使用时 /SCLR接高电平,/G接低电平. - -  从SER每输 ...

  9. linux 下无法输入# 显示为£

    在键盘布局里面,(Keyboard Layout)设置为中国,汉语.解决问题

  10. C#中Json和类的相互转化

    //在NuGet里下载安装 Newtonsoft.Json,再引用. using Newtonsoft.Json; //写一个用户类 public class UserDataInfo { publi ...