转载自: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<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
}
解释下上面的代码:
@Part(“description”) 就是RequestBody实例中包裹的字符串值
@Part MultipartBody.Part file 我们使用MultipartBody.Part类,使我们能够发送实际文件 file就是你要往服务器上传的文件
下面的这段显示文件的URI作为uploadFile(Uri fileUri)方法的参数。如果你选择一个文件,你会在Android的生命周期的onActivityResult()方法内返回。在这个方法中,你可以得到该文件的URI,你就可以通过uploadFile()这个方法来上传文件.
private void uploadFile(Uri fileUri) {
FileUploadService service =
ServiceGenerator.createService(FileUploadService.class);
File file = FileUtils.getFile(this, fileUri);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
String descriptionString = "hello, this is description speaking";
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());
}
});
}
- 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
@GET("/resource/example.zip")
Call<ResponseBody> downloadFileWithFixedUrl();
@GET
Call<ResponseBody> downloadFileWithDynamicUrlSync(@Url String fileUrl);
Call the Request
FileDownloadService downloadService = ServiceGenerator.create(FileDownloadService.class);
Call<ResponseBody> call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> 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<ResponseBody> 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 {
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
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
使用异步的方式
final FileDownloadService downloadService =
ServiceGenerator.create(FileDownloadService.class);
new AsyncTask<Void, Long, Void>() {
@Override
protected Void doInBackground(Void... voids) {
Call<ResponseBody> call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> 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();