Android(安卓)Retrofit2.0实现文件上传和下载
16lz
2021-01-26
转载自:http://blog.csdn.net/Greathfs/article/details/51892499?locationNum=12
这篇主要介绍retrofit框架的上传文件到服务器和从服务器下载功能的实现
上传文件到服务器
首先 retrofit2.0之前上传文件到服务器需要一个叫TypedFile这个类,但是在2.0版本,这个类被取消了,因为2.0以后,retrofit内部集成了okhttp.所以retrofit2.0以后,你需要OkHttp的 RequestBody 或MultipartBody.Part这两个类来往服务器上传文件
下面我们看一个简单的定义好的上传文件的接口:
public interface FileUploadService { @Multipart @POST("upload") Call upload(@Part("description") RequestBody description, @Part MultipartBody.Part file);}
- 1
- 2
- 3
- 4
- 5
- 6
解释下上面的代码:
@Part(“description”) 就是RequestBody实例中包裹的字符串值
@Part MultipartBody.Part file 我们使用MultipartBody.Part类,使我们能够发送实际文件 file就是你要往服务器上传的文件
下面的这段显示文件的URI作为uploadFile(Uri fileUri)方法的参数。如果你选择一个文件,你会在Android的生命周期的onActivityResult()方法内返回。在这个方法中,你可以得到该文件的URI,你就可以通过uploadFile()这个方法来上传文件.
private void uploadFile(Uri fileUri) { // create upload service client FileUploadService service = ServiceGenerator.createService(FileUploadService.class); // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java // use the FileUtils to get the actual file by uri File file = FileUtils.getFile(this, fileUri); // create RequestBody instance from file RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // MultipartBody.Part is used to send also the actual file name MultipartBody.Part body = MultipartBody.Part.createFormData("picture", file.getName(), requestFile); // add another part within the multipart request String descriptionString = "hello, this is description speaking"; RequestBody description = RequestBody.create( MediaType.parse("multipart/form-data"), descriptionString); // finally, execute the request Call call = service.upload(description, body); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { Log.v("Upload", "success"); } @Override public void onFailure(Call call, Throwable t) { Log.e("Upload error:", t.getMessage()); } });}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
从服务器下载文件
定义请求Request
// option 1: a resource relative to your base URL@GET("/resource/example.zip")Call downloadFileWithFixedUrl();// option 2: using a dynamic URL@GETCall downloadFileWithDynamicUrlSync(@Url String fileUrl);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Call the Request
FileDownloadService downloadService = ServiceGenerator.create(FileDownloadService.class);Call call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccess()) { Log.d(TAG, "server contacted and has file"); boolean writtenToDisk = writeResponseBodyToDisk(response.body()); Log.d(TAG, "file download was a success? " + writtenToDisk); } else { Log.d(TAG, "server contact failed"); } } @Override public void onFailure(Call call, Throwable t) { Log.e(TAG, "error"); }});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Save the File
private boolean writeResponseBodyToDisk(ResponseBody body) { try { // todo change the file location/name according to your needs File futureStudioIconFile = new File(getExternalFilesDir(null) + File.separator + "Future Studio Icon.png"); 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; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
如果你下载的文件很大,则使用@Streaming
定义Request
@Streaming@GETCall downloadFileWithDynamicUrlAsync(@Url String fileUrl);
- 1
- 2
- 3
使用异步的方式
final FileDownloadService downloadService = ServiceGenerator.create(FileDownloadService.class);new AsyncTask() { @Override protected Void doInBackground(Void... voids) { Call call = downloadService.downloadFileWithDynamicUrlSync(fileUrl); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccess()) { Log.d(TAG, "server contacted and has file"); boolean writtenToDisk = writeResponseBodyToDisk(response.body()); Log.d(TAG, "file download was a success? " + writtenToDisk); } else { Log.d(TAG, "server contact failed"); } } return null; }}.execute();
更多相关文章
- tcping测试服务器TCP端口
- android pdf
- Android4.1.1下关于采用File.createTempFile创建的临时文件存放
- xamarin开发Android程序示例
- Android开发笔记(二十三)文件对话框FileDialog
- 升级android Sdk出现 SDK Manager failed to insatll错误
- Android(安卓)Studio下载及安装3.0版本
- Android学习笔记之反编译工具介绍及下载(Class文件反编译,xml文件
- 记Android(安卓)Studio自定义属性访问不了的问题