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;
  }
Пример #2
0
 public void doFetch() {
   synchronized (this) {
     if (consumers == null) {
       awaitingFetch = false;
       return;
     }
   }
   ImageDecoder imgd = getDecoder();
   if (imgd == null) {
     badDecoder();
   } else {
     setDecoder(imgd);
     try {
       imgd.produceImage();
     } catch (IOException e) {
       e.printStackTrace();
       // the finally clause will send an error.
     } catch (ImageFormatException e) {
       e.printStackTrace();
       // the finally clause will send an error.
     } finally {
       removeDecoder(imgd);
       if (Thread.currentThread().isInterrupted() || !Thread.currentThread().isAlive()) {
         errorAllConsumers(imgd.queue, true);
       } else {
         errorAllConsumers(imgd.queue, false);
       }
     }
   }
 }
Пример #3
0
 public synchronized boolean isConsumer(ImageConsumer ic) {
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id.isConsumer(ic)) {
       return true;
     }
   }
   return ImageConsumerQueue.isConsumer(consumers, ic);
 }
  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;
  }
Пример #5
0
 private synchronized void removeDecoder(ImageDecoder mydecoder) {
   doneDecoding(mydecoder);
   ImageDecoder idprev = null;
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id == mydecoder) {
       if (idprev == null) {
         decoders = id.next;
       } else {
         idprev.next = id.next;
       }
       break;
     }
     idprev = id;
   }
 }
  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);
    }
  }
Пример #7
0
 synchronized void addConsumer(ImageConsumer ic, boolean produce) {
   checkSecurity(null, false);
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id.isConsumer(ic)) {
       // This consumer is already being fed.
       return;
     }
   }
   ImageConsumerQueue cq = consumers;
   while (cq != null && cq.consumer != ic) {
     cq = cq.next;
   }
   if (cq == null) {
     cq = new ImageConsumerQueue(this, ic);
     cq.next = consumers;
     consumers = cq;
   } else {
     if (!cq.secure) {
       Object context = null;
       SecurityManager security = System.getSecurityManager();
       if (security != null) {
         context = security.getSecurityContext();
       }
       if (cq.securityContext == null) {
         cq.securityContext = context;
       } else if (!cq.securityContext.equals(context)) {
         // If there are two different security contexts that both
         // have a handle on the same ImageConsumer, then there has
         // been a security breach and whether or not they trade
         // image data is small fish compared to what they could be
         // trading.  Throw a Security exception anyway...
         errorConsumer(cq, false);
         throw new SecurityException("Applets are trading image data!");
       }
     }
     cq.interested = true;
   }
   if (produce && decoder == null) {
     startProduction();
   }
 }
Пример #8
0
 private void setDecoder(ImageDecoder mydecoder) {
   ImageConsumerQueue cq;
   synchronized (this) {
     mydecoder.next = decoders;
     decoders = mydecoder;
     decoder = mydecoder;
     cq = consumers;
     mydecoder.queue = cq;
     consumers = null;
     awaitingFetch = false;
   }
   while (cq != null) {
     if (cq.interested) {
       // Now that there is a decoder, security may have changed
       // so reverify it here, just in case.
       if (!checkSecurity(cq.securityContext, true)) {
         errorConsumer(cq, false);
       }
     }
     cq = cq.next;
   }
 }
Пример #9
0
 public synchronized void removeConsumer(ImageConsumer ic) {
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     id.removeConsumer(ic);
   }
   consumers = ImageConsumerQueue.removeConsumer(consumers, ic, false);
 }