【问题标题】:Retrofit 2 download image and save to folderRetrofit 2 下载图像并保存到文件夹
【发布时间】:2020-01-15 16:16:24
【问题描述】:

我需要从服务器下载图像并将其保存到文件夹中,所以我使用的是 Retrofit 2。

问题是当我在文件夹中查找保存的图像时它是空的,我尝试调试并看到位图为空。

我不明白为什么,这是我的代码:

@GET("images/{userId}/{imageName}")
@Streaming
Call<ResponseBody> downloadImage(@Path("userId") String userId, @Path("imageName") String imageName);

下载图片代码:

 private void downloadImage(final int position) {
    String url = "htttp://myserver.com/";
        retrofitImage = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

    imageApi = retrofitImage.create(BlastApiService.class);

    String userId = feedList.get(position).getUserId();
    String fileName = feedList.get(position).getFile();

    Call<ResponseBody> imageCall = imageApi.downloadImage(userId, fileName );
    imageCall.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if(response.isSuccess()){
                String fileName = feedList.get(position).getFile();
                InputStream is = response.body().byteStream();
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                saveImage1(bitmap, fileName);
            } else{
                try {
                    Log.d("TAG", "response error: "+response.errorBody().string().toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.d("TAG", "Image download error: " + t.getLocalizedMessage());
        }
    });

}

这是保存图片的方法。

 private void saveImage1(Bitmap imageToSave, String fileName) {
    // get the path to sdcard
    File sdcard = Environment.getExternalStorageDirectory();
    // to this path add a new directory path
    File dir = new File(sdcard.getAbsolutePath() + "/FOLDER_NAME/");
    // create this directory if not already created
    dir.mkdir();
    // create the file in which we will write the contents
    File file = new File(dir, fileName);
    try {
        FileOutputStream out = new FileOutputStream(file);
        imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
        counter++;
       // if (counter < feedList.size()) {
            //downloadImage(counter);
        //} else {
            setImage();
        //}
    } catch (Exception e) {
        e.printStackTrace();
    }
}

【问题讨论】:

  • 你为什么不使用专用的 ImageLoader,比如 Glide 或 UIL?只是好奇并试图了解问题的背景。
  • 字符串 url = "htttp://myserver.com/";是错的! 3 t 在 Http 中。
  • @ElvisChweya 客户端希望我将图像下载到文件夹,然后从本地文件夹显示,而不是直接从服务器加载图像。因为应用程序只有一个图像视图并且 API 返回了 10 个图像,所以客户端不希望用户等待几秒钟来显示来自服务器的图像(1 到 2 MB 图像)。
  • @Zookey,但这就是图像加载器所做的。他们只下载一次图像并存储在 sdcard 上,然后连续调用 load 只需从 storage/sdcard 加载。另外,它们在服务器端更新时会进行内存缓存和更新图像。
  • 但是假设您仍然需要下载图像然后从存储中加载,Glide 只能用于下载图像。为此使用改造是不必要的。请不要使用 Retrofit 进行图像加载。使用 Glide 加载存储在存储中的图像的好处是巨大的。

标签: android retrofit android-bitmap retrofit2


【解决方案1】:

这对我有用:

public static boolean writeResponseBody(ResponseBody body, String path) {
    try {

        File file = 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(file);

            while (true) {
                int read = inputStream.read(fileReader);

                if (read == -1) {
                    break;
                }
                outputStream.write(fileReader, 0, read);
                //fileSizeDownloaded += read;
            }

            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;
    }
}

调用此方法后可以从路径获取图片:

boolean result = writeResponseBody(body, path);
if(result) {
    Bitmap bitmap = BitmapFactory.decodeFile(path)
}

【讨论】:

  • 您可以简单地保存文件,生成 Uri 并将其传递给 ImageView,而不是将其加载到内存中。
【解决方案2】:
private boolean writeResponseBodyToDisk(ResponseBody body, String name) {
    try {
        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/MyApp";
        File dir = new File(path);
        if (!dir.exists())
            dir.mkdirs();


        File futureStudioIconFile = new File(path, name + ".pdf");//am saving pdf file
        if (futureStudioIconFile.exists())
            futureStudioIconFile.delete();
        futureStudioIconFile.createNewFile();


        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;
            }

            outputStream.flush();

            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2021-01-07
    • 1970-01-01
    • 2015-11-04
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    相关资源
    最近更新 更多