Android之网络请求10————Retrofit的进阶使用

文章目录

  • Android之网络请求10————Retrofit的进阶使用
      • 一.前言
      • 二.Retrfit文件上传
        • 1.创建描述网络请求的接口
        • 2.具体使用
      • 三.Retrfit图片上传
        • 1.创建描述网络请求的接口
        • 2.具体使用
      • 四.Retrfit Json字符串上传
        • 1.创建描述网络请求的接口
        • 2.具体使用
      • 五.Retrfit大文件下载
        • 1.ApiService
        • 2.DownLoadManager
        • 3.具体使用
        • 4.进一步优化
      • 七.参考资料
      • 八.文章索引

一.前言

上一节中我们对Retrofit进行了介绍,包括他的简单使用和注解。这一篇我们学习他的进阶使用,包括文件图片Json字符串的上传,以及大文件的断点下载,还有和Rxjava的混合使用

准备工作:

  • 添加依赖
  • 设置权限

二.Retrfit文件上传

1.创建描述网络请求的接口

 public interface FileUploadService {   @Multipart //表示发送form-encoded的数据(适用于 有文件 上传的场景) @POST("upload") Call<ResponseBody> upload(@Part("description") RequestBody description,                          @Part MultipartBody.Part file);}

2.具体使用

// 创建 RequestBody,用于封装 请求RequestBodyRequestBody requestFile =        RequestBody.create(MediaType.parse("multipart/form-data"), file);// MultipartBody.Part is used to send also the actual file nameMultipartBody.Part body =        MultipartBody.Part.createFormData("image", file.getName(), requestFile);// 添加描述String descriptionString = "hello, 这是文件描述";RequestBody description =        RequestBody.create(                MediaType.parse("multipart/form-data"), descriptionString);// 执行请求Call<ResponseBody> call = service.upload(description, body);call.enqueue(new Callback<ResponseBody>() {    @Override    public void onResponse(Call<ResponseBody> call,                           Response<ResponseBody> response) {        Log.v("Upload", "success");    }    @Override    public void onFailure(Call<ResponseBody> call, Throwable t) {        Log.e("Upload error:", t.getMessage());    }});

三.Retrfit图片上传

1.创建描述网络请求的接口

//上传一张图片@Multipart @POST("you methd url upload/")Call<ResponseBody> uploadFile(@Part("avatar\\\\"; filename=\\\\"avatar.jpg") RequestBody file);//上传图片数量不定  @Multipart@POST("{url}")Observable<ResponseBody> uploadFiles(        @Path("url") String url,        @Part("filename") String description,        @PartMap() Map<String, RequestBody> maps);//上传图片数量不定方法2@Multipart@POST("{url}")Observable<ResponseBody> uploads(        @Path("url") String url,        @Part("description") RequestBody description,        @Part("filekey") MultipartBody.Part file);

2.具体使用

具体的使用和上面文件的上传差不多,不过图片可以设置Content-Type,如

   RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), mFile);

四.Retrfit Json字符串上传

1.创建描述网络请求的接口

@POST("/uploadJson")Observable<ResponseBody> uploadjson(@Body RequestBody jsonBody);

2.具体使用

RequestBody body= RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), jsonString);// 执行请求Call<ResponseBody> call = service.uploadJson(description, body);call.enqueue(new Callback<ResponseBody>() {    @Override    public void onResponse(Call<ResponseBody> call,                           Response<ResponseBody> response) {        Log.v("Upload", "success");    }    @Override    public void onFailure(Call<ResponseBody> call, Throwable t) {        Log.e("Upload error:", t.getMessage());    }});

五.Retrfit大文件下载

1.ApiService

public interface ApiService {  @Streaming//大文件官方建议用 @Streaming 来进行注解,不然会出现IO异常,小文件可以忽略不注入。  @GET  Observable<ResponseBody> downloadFile(@Url String   fileUrl);}

2.DownLoadManager

/** * 下载管理者 来进行文件写入,类型判断等 */public class DownLoadManager {    private static final String TAG = "DownLoadManager";    private static String APK_CONTENTTYPE = "application/vnd.android.package-archive";    private static String PNG_CONTENTTYPE = "image/png";    private static String JPG_CONTENTTYPE = "image/jpg";    private static String fileSuffix = "";    public static boolean writeResponseBodyToDisk(Context context, ResponseBody body) {        Log.d(TAG, "contentType:>>>>" + body.contentType().toString());        String type = body.contentType().toString();        if (type.equals(APK_CONTENTTYPE)) {            fileSuffix = ".apk";        } else if (type.equals(PNG_CONTENTTYPE)) {            fileSuffix = ".png";        } // 其他类型同上 自己判断加入.....        String path = context.getExternalFilesDir(null) + File.separator + System.currentTimeMillis() + fileSuffix;        Log.d(TAG, "path:>>>>" + path);                //文件的写入        try {             File futureStudioIconFile = new File(path);            InputStream inputStream = null;            OutputStream outputStream = null;            try {                byte[] fileReader = new byte[4096];                long fileSize = body.contentLength();                long fileSizeDownloaded = 0;                inputStream = body.byteStream();                outputStream = new FileOutputStream(futureStudioIconFile);                while (true) {                    int read = inputStream.read(fileReader);                    if (read == -1) {                        break;                    }                    outputStream.write(fileReader, 0, read);                    fileSizeDownloaded += read;                    Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);                }                outputStream.flush();                return true;            } catch (IOException e) {                return false;            } finally {                if (inputStream != null) {                    inputStream.close();                }                if (outputStream != null) {                    outputStream.close();                }            }        } catch (IOException e) {            return false;        }    }}

3.具体使用

 OkHttpClient okHttpClient = new OkHttpClient.Builder().build();        Retrofit retrofit = new Retrofit.Builder().client(okHttpClient).baseUrl(url).build();        Api Service apiService = retrofit.create(ApiService.class);        apiService.download(url1, new Subscriber<ResponseBody>() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(ResponseBody responseBody) {                if (DownLoadManager.writeResponseBodyToDisk(MainActivity.this, responseBody)) {                    Toast.makeText(MainActivity.this, "Download is sucess", Toast.LENGTH_LONG).show();                }            }        });

4.进一步优化

上面只是一些简单的下载,我们还可以加入更多的优化,比如在header中加入上次下载的进度大小,就可以实现基本的断点下载了。

我们可以请求到文件总长度的时候,均分三段大小区间,来开启三个新线程去下载,下载完后再以唯一的文件ID,将三段文件以此追加到一个文件就可以了,来实现多线程下载。

七.参考资料

Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
Retrofit 2.0 超能实践(四),完成大文件断点下载

八.文章索引

Android之网络请求1————HTTP协议
Android之网络请求2————OkHttp的基本使用
Android之网络请求3————OkHttp的拦截器和封装
Android之网络请求4————OkHttp源码1:框架
Android之网络请求5————OkHttp源码2:发送请求
Android之网络请求6————OkHttp源码3:拦截器链
Android之网络请求7————OkHttp源码4:网络操作
Android之网络请求8————OkHttp源码5:缓存相关
Android之网络请求9————Retrofit的简单使用
Android之网络请求10————Retrofit的进阶使用
Android之网络请求11————Retrofit的源码分析

更多相关文章

  1. Android(安卓)网络请求详解
  2. Android上鲜为人知的UI控件介绍和使用
  3. 【Android开发】多媒体应用开发-使用MediaPlayer播放音频
  4. Android开发笔记之【Android(安卓)API】Android(安卓)4.1 API官
  5. Android内存管理-SoftReference的使用
  6. okhttp的应用详解与源码解析--okhttp客户端应用
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. Android控制ScrollView滑动速度
  2. 新版Qt可以支持Android和IOS平台
  3. android下联网
  4. 【ArcGIS Android(安卓)10.2.9】5. WMSLa
  5. Android中的SQLite使用
  6. Android(安卓)PinnedSectionListView异常
  7. 8、RxJava+Retrofit+okhttp上传多张图片
  8. Android(安卓)在线升级APK
  9. android drawable setBounds()
  10. android: MapView加载多个 overlay 内存