Android之网络请求10————Retrofit的进阶使用
16lz
2022-05-04
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的源码分析
更多相关文章
- Android(安卓)网络请求详解
- Android上鲜为人知的UI控件介绍和使用
- 【Android开发】多媒体应用开发-使用MediaPlayer播放音频
- Android开发笔记之【Android(安卓)API】Android(安卓)4.1 API官
- Android内存管理-SoftReference的使用
- okhttp的应用详解与源码解析--okhttp客户端应用
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用