zoukankan      html  css  js  c++  java
  • Android开发 retrofit下载与上传

    前言

       此博客只讲解retrofit下载与上传的使用,其实与其说是retrofit的下载与上传还不如说,依然是Okhttp的下载与上传.如果你需要了解retrofit入门请查看这篇博客(此博客不在详细讲解一些基础的东西):https://www.cnblogs.com/guanxinjing/p/11594249.html

    下载

      设置下载接口

    public interface HttpList {
    
        @Streaming //注解这个请求将获取数据流,此后将不会这些获取的请求数据保存到内存中,将交与你操作.
        @GET
        Call<ResponseBody> download(@Url String url);
    
    
    }

    这里有一个很重要的东西! @Url属性, 这个属性是你导入的下载地址. 它可以是绝对地址和可以是相对地址,当你使用这个属性的时候,Retrofit设置基础UrlbaseUrl("http://p.gdown.baidu.com/") 将自动判断地址是绝对还是相对,从而选择拼接Url还是替换Url !

      请求下载

    private void downloadFile() {
            final File file = new File(getExternalCacheDir(), "demo.apk");
            if (file.exists()) {
                file.delete();
            }
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://p.gdown.baidu.com/")//base的网络地址
                    .callbackExecutor(Executors.newSingleThreadExecutor())//设置线程,如果不设置下载在读取流的时候就会报错
                    .build();
    
            HttpList httpList = retrofit.create(HttpList.class);
    
            Call<ResponseBody> call = httpList.download(DOWNLOAD_URL_PATH);//下载地址  太长了所以我用DOWNLOAD_URL_PATH封装了一下,不要误解
    
            call.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try {
                        long total = response.body().contentLength();//需要下载的总大小
                        long current = 0;
                        InputStream inputStream = response.body().byteStream();
                        FileOutputStream fileOutputStream = new FileOutputStream(file);
                        byte[] bytes = new byte[1024];
                        int len = 0;
                        while ((len = inputStream.read(bytes)) != -1) {
                            fileOutputStream.write(bytes, 0, len);
                   fileOutputStream.flush(); current
    = current + len; Log.e(TAG, "已经下载=" + current + " 需要下载=" + total); } fileOutputStream.flush(); fileOutputStream.close(); inputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { } }); }

    以上的下载实现的关键点,其实是ResponseBody,而这个其实就是okhttp的请求接口后返回的响应body. Retrofit并没有对这个进行封装,所以如果你了解okhttp的使用,应该是轻轻松松的.

    上传

       上传一般有好几种情况:

    •   不需要进度的上传
    •   需要进度的上传
    •   批量上传

    无进度的文件上传

      接口服务类

    public interface HttpList {
        @Multipart
        @POST("test/upfile")
        Call<ResponseBody> upFile(@Part MultipartBody.Part part);
    }

    注意这里的Body是 MultipartBody

      上传实现

    /**
         * 无进度上传
         */
        private void updateFile(){
            final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
            if (!imageFile.getParentFile().exists()){
                imageFile.getParentFile().mkdirs();
            }
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
                    .callbackExecutor(Executors.newSingleThreadExecutor())
                    .build();
            HttpList list = retrofit.create(HttpList.class);
    
            //
            /*
             * "image/jpg" 是你要上传的文件的格式 这个格式并不是固定的,是根据你的项目使用那些何种key也有很多是使用下面这个:
             *  RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
             */
            RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), imageFile);
    
    
            //注意这里的file是对应MultipartBody上传文件的key名称
            MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile);
    
            Call<ResponseBody> call = list.upFile(multipartBody);
            call.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try {
                        Log.e(TAG, "onResponse: 上传成功 "+response.body().string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
    
                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
    
                }
            });
    
    
        }

    有进度的文件上传

    /**
         * 有进度的上传
         */
        private void updateFile(){
            final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
            if (!imageFile.getParentFile().exists()){
                imageFile.getParentFile().mkdirs();
            }
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
                    .callbackExecutor(Executors.newSingleThreadExecutor())
                    .build();
            HttpList list = retrofit.create(HttpList.class);
    RequestBody requestFile
    = new RequestBody() { @Nullable @Override public MediaType contentType() { return MediaType.parse("image/jpg");//这里返回上传的格式 根据项目情况也可以切换成"multipart/form-data" 等等其他格式 } @Override public void writeTo(BufferedSink sink) throws IOException { RandomAccessFile randomAccessFile = new RandomAccessFile(imageFile, "rw"); long totalLength = 0; long currentUpLength = 0; if (totalLength == 0) { totalLength = randomAccessFile.length(); } byte[] bytes = new byte[2048]; int len = 0; try { while ((len = randomAccessFile.read(bytes)) != -1) { sink.write(bytes, 0, len); currentUpLength = currentUpLength + len; Log.e(TAG, "writeTo: totalLength="+totalLength + " currentUpLength="+currentUpLength); } }catch (Exception e){ Log.e(TAG, "上传中断"); }finally { randomAccessFile.close();//关闭流 Log.e(TAG, "流关闭"); } } }; MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile); Call<ResponseBody> call = list.upFile(multipartBody); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { Log.e(TAG, "onResponse: 上传成功 "+response.body().string()); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { } }); }

    批量上传文件(无对应key的批量上传)

       接口服务类

    public interface HttpList {
        @Multipart
        @POST("test/upfileList")
        Call<ResponseBody> upFileList(@Part List<MultipartBody.Part> partList);
    }

    其他与单个上传一致

    批量上传文件(有对应key的批量上传)

       接口服务类

    public interface HttpList {
        @Multipart
        @POST("test/upfileList")
        Call<ResponseBody> upFileList(@PartMap Map<String, RequestBody> map);
    }

      实现批量上传

    private void updateFile3(){
            final File imageFile1 = new File(getExternalCacheDir() + "/image/demo_1.jpg");
            final File imageFile2 = new File(getExternalCacheDir() + "/image/demo_2.jpg");
            final File imageFile3 = new File(getExternalCacheDir() + "/image/demo_3.jpg");
            RequestBody requestFile1 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile1);
            RequestBody requestFile2 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile2);
            RequestBody requestFile3 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile3);
            Map<String, RequestBody> map = new HashMap<>();
            map.put("file1", requestFile1); //file1 就是需要上传每个文件的key名称
            map.put("file2", requestFile2);
            map.put("file3", requestFile3);
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
                    .callbackExecutor(Executors.newSingleThreadExecutor())
                    .build();
            HttpList list = retrofit.create(HttpList.class);
            Call<ResponseBody> call = list.upFileList(map);
            call.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    //上传成功
    
                }
    
                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
    
                }
            });
    
        }

    end

  • 相关阅读:
    linux MySQL安装指南
    Ubuntu MySQL常用命令
    linux下 mysql 忘记root用户密码解决办法
    ubuntu mysql 启动命令/配置my.cnf
    Ubuntu中给mysql添加新用户并分配权限
    各种 ADSL Modem 及路由器的端口映射方法
    (转)有关SharePoint页面定制的若干细节
    获取Excel中的Sheet的名称
    获取excel表单中的数据
    如何用Excel 2007同步MOSS列表(转)
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/11609328.html
Copyright © 2011-2022 走看看