Пример #1
0
  /**
   * Asynchronously fulfills the request without a {@link ImageView} or {@link Target}, and invokes
   * the target {@link Callback} with the result. This is useful when you want to warm up the cache
   * with an image.
   *
   * <p><em>Note:</em> The {@link Callback} param is a strong reference and will prevent your {@link
   * android.app.Activity} or {@link android.app.Fragment} from being garbage collected until the
   * request is completed.
   */
  public void fetch(Callback callback) {
    long started = System.nanoTime();

    if (deferred) {
      throw new IllegalStateException("Fit cannot be used with fetch.");
    }
    if (data.hasImage()) {
      // Fetch requests have lower priority by default.
      if (!data.hasPriority()) {
        data.priority(Priority.LOW);
      }

      Request request = createRequest(started);
      String key = createKey(request, new StringBuilder());

      if (shouldReadFromMemoryCache(memoryPolicy)) {
        Bitmap bitmap = picasso.quickMemoryCacheCheck(key);
        if (bitmap != null) {
          if (picasso.loggingEnabled) {
            log(OWNER_MAIN, VERB_COMPLETED, request.plainId(), "from " + MEMORY);
          }
          if (callback != null) {
            callback.onSuccess();
          }
          return;
        }
      }

      Action action =
          new FetchAction(picasso, request, memoryPolicy, networkPolicy, tag, key, callback);
      picasso.submit(action);
    }
  }
Пример #2
0
  Bitmap hunt() throws IOException {
    Bitmap bitmap;

    if (!skipMemoryCache) {
      bitmap = cache.get(key);
      if (bitmap != null) {
        stats.dispatchCacheHit();
        loadedFrom = MEMORY;
        return bitmap;
      }
    }

    bitmap = decode(data);

    if (bitmap != null) {
      stats.dispatchBitmapDecoded(bitmap);
      if (data.needsTransformation() || exifRotation != 0) {
        synchronized (DECODE_LOCK) {
          if (data.needsMatrixTransform() || exifRotation != 0) {
            bitmap = transformResult(data, bitmap, exifRotation);
          }
          if (data.hasCustomTransformations()) {
            bitmap = applyCustomTransformations(data.transformations, bitmap);
          }
        }
        stats.dispatchBitmapTransformed(bitmap);
      }
    }

    return bitmap;
  }
  @Test
  public void bitmapConfig() throws Exception {
    for (Bitmap.Config config : Bitmap.Config.values()) {
      Request data = new Request.Builder(URI_1).config(config).build();
      Request copy = data.buildUpon().build();

      assertThat(createBitmapOptions(data).inPreferredConfig).isSameAs(config);
      assertThat(createBitmapOptions(copy).inPreferredConfig).isSameAs(config);
    }
  }
Пример #4
0
  /** Create the request optionally passing it through the request transformer. */
  private Request createRequest(long started) {
    int id = nextId.getAndIncrement();

    Request request = data.build();
    request.id = id;
    request.started = started;

    boolean loggingEnabled = picasso.loggingEnabled;
    if (loggingEnabled) {
      log(OWNER_MAIN, VERB_CREATED, request.plainId(), request.toString());
    }

    Request transformed = picasso.transformRequest(request);
    if (transformed != request) {
      // If the request was changed, copy over the id and timestamp from the original.
      transformed.id = id;
      transformed.started = started;

      if (loggingEnabled) {
        log(OWNER_MAIN, VERB_CHANGED, transformed.logId(), "into " + transformed);
      }
    }

    return transformed;
  }
Пример #5
0
 private Bitmap decodeResource(Resources resources, int id, Request data) {
   BitmapFactory.Options bitmapOptions = createBitmapOptions(data);
   if (data.hasSize()) {
     bitmapOptions.inJustDecodeBounds = true;
     BitmapFactory.decodeResource(resources, id, bitmapOptions);
     calculateInSampleSize(data.targetWidth, data.targetHeight, bitmapOptions);
   }
   return BitmapFactory.decodeResource(resources, id, bitmapOptions);
 }
Пример #6
0
  private Bitmap decodeStream(InputStream stream, Request data) throws IOException {
    if (stream == null) {
      return null;
    }
    MarkableInputStream markStream = new MarkableInputStream(stream);
    stream = markStream;

    long mark = markStream.savePosition(MARKER);

    boolean isWebPFile = Utils.isWebPFile(stream);
    markStream.reset(mark);
    // When decode WebP network stream, BitmapFactory throw JNI Exception and make app crash.
    // Decode byte array instead
    if (isWebPFile) {
      byte[] bytes = Utils.toByteArray(stream);
      BitmapFactory.Options options = createBitmapOptions(data);
      if (data.hasSize()) {
        options.inJustDecodeBounds = true;

        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        calculateInSampleSize(
            data.maxWidth, data.maxHeight, data.targetWidth, data.targetHeight, options);
      }
      return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
    } else {
      BitmapFactory.Options options = createBitmapOptions(data);
      if (data.hasSize()) {
        options.inJustDecodeBounds = true;

        BitmapFactory.decodeStream(stream, null, options);
        calculateInSampleSize(
            data.maxWidth, data.maxHeight, data.targetWidth, data.targetHeight, options);

        markStream.reset(mark);
      }
      return BitmapFactory.decodeStream(stream, null, options);
    }
  }
 static BitmapFactory.Options createBitmapOptions(Request paramRequest) {
   boolean bool = paramRequest.hasSize();
   if (paramRequest.config != null) {}
   for (int i = 1; ; i = 0) {
     Object localObject = null;
     if ((bool) || (i != 0)) {
       BitmapFactory.Options localOptions = new BitmapFactory.Options();
       localOptions.inJustDecodeBounds = bool;
       localObject = localOptions;
       if (i != 0) {
         localOptions.inPreferredConfig = paramRequest.config;
         localObject = localOptions;
       }
     }
     return (BitmapFactory.Options) localObject;
   }
 }
Пример #8
0
  private Bitmap decodeStream(InputStream stream, Request data) throws IOException {
    if (stream == null) {
      return null;
    }
    BitmapFactory.Options options = null;
    if (data.hasSize()) {
      options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;

      MarkableInputStream markStream = new MarkableInputStream(stream);
      stream = markStream;

      long mark = markStream.savePosition(1024); // Mirrors BitmapFactory.cpp value.
      BitmapFactory.decodeStream(stream, null, options);
      calculateInSampleSize(data.targetWidth, data.targetHeight, options);

      markStream.reset(mark);
    }
    return BitmapFactory.decodeStream(stream, null, options);
  }
Пример #9
0
  @Override
  public void run() {
    try {
      Thread.currentThread().setName(Utils.THREAD_PREFIX + data.getName());

      result = hunt();

      if (result == null) {
        dispatcher.dispatchFailed(this);
      } else {
        dispatcher.dispatchComplete(this);
      }
    } catch (IOException e) {
      exception = e;
      dispatcher.dispatchRetry(this);
    } catch (Exception e) {
      exception = e;
      dispatcher.dispatchFailed(this);
    } finally {
      Thread.currentThread().setName(Utils.THREAD_IDLE_NAME);
    }
  }
Пример #10
0
  static Bitmap transformResult(Request data, Bitmap result, int exifRotation) {
    int inWidth = result.getWidth();
    int inHeight = result.getHeight();

    int drawX = 0;
    int drawY = 0;
    int drawWidth = inWidth;
    int drawHeight = inHeight;

    Matrix matrix = new Matrix();

    if (data.needsMatrixTransform()) {
      int targetWidth = data.targetWidth;
      int targetHeight = data.targetHeight;

      float targetRotation = data.rotationDegrees;
      if (targetRotation != 0) {
        if (data.hasRotationPivot) {
          matrix.setRotate(targetRotation, data.rotationPivotX, data.rotationPivotY);
        } else {
          matrix.setRotate(targetRotation);
        }
      }

      if (data.centerCrop) {
        float widthRatio = targetWidth / (float) inWidth;
        float heightRatio = targetHeight / (float) inHeight;
        float scale;
        if (widthRatio > heightRatio) {
          scale = widthRatio;
          int newSize = (int) Math.ceil(inHeight * (heightRatio / widthRatio));
          drawY = (inHeight - newSize) / 2;
          drawHeight = newSize;
        } else {
          scale = heightRatio;
          int newSize = (int) Math.ceil(inWidth * (widthRatio / heightRatio));
          drawX = (inWidth - newSize) / 2;
          drawWidth = newSize;
        }
        matrix.preScale(scale, scale);
      } else if (data.centerInside) {
        float widthRatio = targetWidth / (float) inWidth;
        float heightRatio = targetHeight / (float) inHeight;
        float scale = widthRatio < heightRatio ? widthRatio : heightRatio;
        matrix.preScale(scale, scale);
      } else if (targetWidth != 0
          && targetHeight != 0 //
          && (targetWidth != inWidth || targetHeight != inHeight)) {
        // If an explicit target size has been specified and they do not match the results bounds,
        // pre-scale the existing matrix appropriately.
        float sx = targetWidth / (float) inWidth;
        float sy = targetHeight / (float) inHeight;
        matrix.preScale(sx, sy);
      }
    }

    if (exifRotation != 0) {
      matrix.preRotate(exifRotation);
    }

    Bitmap newResult =
        Bitmap.createBitmap(result, drawX, drawY, drawWidth, drawHeight, matrix, true);
    if (newResult != result) {
      result.recycle();
      result = newResult;
    }

    return result;
  }
Пример #11
0
  /**
   * Asynchronously fulfills the request into the specified {@link ImageView} and invokes the target
   * {@link Callback} if it's not {@code null}.
   *
   * <p><em>Note:</em> The {@link Callback} param is a strong reference and will prevent your {@link
   * android.app.Activity} or {@link android.app.Fragment} from being garbage collected. If you use
   * this method, it is <b>strongly</b> recommended you invoke an adjacent {@link
   * Picasso#cancelRequest(android.widget.ImageView)} call to prevent temporary leaking.
   */
  public void into(ImageView target, Callback callback) {
    long started = System.nanoTime();
    if (picasso.checkMainThreadsEnabled) {
      checkMain();
    }

    if (target == null) {
      throw new IllegalArgumentException("Target must not be null.");
    }

    if (!data.hasImage()) {
      picasso.cancelRequest(target);
      if (setPlaceholder) {
        setPlaceholder(target, getPlaceholderDrawable());
      }
      return;
    }

    if (deferred) {
      if (data.hasSize()) {
        throw new IllegalStateException("Fit cannot be used with resize.");
      }
      int width = target.getWidth();
      int height = target.getHeight();
      if (width == 0 || height == 0) {
        if (setPlaceholder) {
          setPlaceholder(target, getPlaceholderDrawable());
        }
        picasso.defer(target, new DeferredRequestCreator(this, target, callback));
        return;
      }
      data.resize(width, height);
    }

    Request request = createRequest(started);
    String requestKey = createKey(request);

    if (shouldReadFromMemoryCache(memoryPolicy)) {
      Bitmap bitmap = picasso.quickMemoryCacheCheck(requestKey);
      if (bitmap != null) {
        picasso.cancelRequest(target);
        setBitmap(target, picasso.context, bitmap, MEMORY, noFade, picasso.indicatorsEnabled);
        if (picasso.loggingEnabled) {
          log(OWNER_MAIN, VERB_COMPLETED, request.plainId(), "from " + MEMORY);
        }
        if (callback != null) {
          callback.onSuccess();
        }
        return;
      }
    }

    if (setPlaceholder) {
      setPlaceholder(target, getPlaceholderDrawable());
    }

    Action action =
        new ImageViewAction(
            picasso,
            target,
            request,
            memoryPolicy,
            networkPolicy,
            errorResId,
            errorDrawable,
            requestKey,
            tag,
            callback,
            noFade);

    picasso.enqueueAndSubmit(action);
  }