private Bitmap decodeWithOOMHandling(URI imageUri) throws IOException {
    Bitmap result = null;
    ImageDecoder decoder = new ImageDecoder(imageUri, downloader, options);
    decoder.setLoggingEnabled(loggingEnabled);
    for (int attempt = 1; attempt <= ATTEMPT_COUNT_TO_DECODE_BITMAP; attempt++) {
      try {
        ViewScaleType viewScaleType = ViewScaleType.fromImageView(imageView);
        result = decoder.decode(targetSize, options.getImageScaleType(), viewScaleType);
      } catch (OutOfMemoryError e) {
        L.e(e);

        switch (attempt) {
          case 1:
            System.gc();
            break;
          case 2:
            configuration.memoryCache.clear();
            System.gc();
            break;
          case 3:
            throw e;
        }
        // Wait some time while GC is working
        SystemClock.sleep(attempt * 1000);
        continue;
      }
      break;
    }
    return result;
  }
  private Bitmap decodeImage(URI imageUri) throws IOException {
    Bitmap bmp = null;

    if (configuration.handleOutOfMemory) {
      bmp = decodeWithOOMHandling(imageUri);
    } else {
      ImageDecoder decoder = new ImageDecoder(imageUri, downloader, options);
      decoder.setLoggingEnabled(loggingEnabled);
      ViewScaleType viewScaleType = ViewScaleType.fromImageView(imageView);
      bmp = decoder.decode(targetSize, options.getImageScaleType(), viewScaleType);
    }
    return bmp;
  }
  private void saveImageOnDisc(File targetFile) throws IOException, URISyntaxException {
    int width = configuration.maxImageWidthForDiscCache;
    int height = configuration.maxImageHeightForDiscCache;
    if (width > 0 || height > 0) {
      // Download, decode, compress and save image
      ImageSize targetImageSize = new ImageSize(width, height);
      ImageDecoder decoder = new ImageDecoder(new URI(uri), downloader, options);
      decoder.setLoggingEnabled(loggingEnabled);
      Bitmap bmp =
          decoder.decode(targetImageSize, ImageScaleType.IN_SAMPLE_INT, ViewScaleType.FIT_INSIDE);
      if (bmp != null) {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(targetFile), BUFFER_SIZE);
        boolean compressedSuccessfully = false;
        try {
          compressedSuccessfully =
              bmp.compress(
                  configuration.imageCompressFormatForDiscCache,
                  configuration.imageQualityForDiscCache,
                  os);
        } finally {
          IoUtils.closeSilently(os);
        }
        if (compressedSuccessfully) {
          bmp.recycle();
          return;
        }
      }
    }

    // If previous compression wasn't needed or failed
    // Download and save original image
    InputStream is = downloader.getStream(new URI(uri));
    try {
      OutputStream os = new BufferedOutputStream(new FileOutputStream(targetFile), BUFFER_SIZE);
      try {
        IoUtils.copyStream(is, os);
      } finally {
        IoUtils.closeSilently(os);
      }
    } finally {
      IoUtils.closeSilently(is);
    }
  }