Android Retrofit2.0实现文件上传和下载

转载自: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
@GET
Call 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
@GET
Call 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();            

你可能感兴趣的:(android)