nostra13/Android-Universal-Image-Loader · error · IllegalArgumentException

ImageAware should wrap ImageView. ImageViewAware is…

Error message

ImageAware should wrap ImageView. ImageViewAware is expected.

What it means

RoundedVignetteBitmapDisplayer extends RoundedBitmapDisplayer and repeats the same guard: display() only accepts ImageViewAware targets, throwing IllegalArgumentException otherwise. The vignette drawable it creates must be set on an ImageView via setImageDrawable, so non-ImageView awares are rejected. The failure happens at display time, after download and decode succeeded.

Solutions

  1. Supply an ImageViewAware target (or the ImageView itself) when the vignette displayer is active
  2. Split options: keep a displayer-free variant for NonViewAware/prefetch loads
  3. Substitute a custom BitmapDisplayer without the instanceof check for non-view pipelines

Example fix

// before
imageLoader.displayImage(uri, nonViewAware, baseOptions); // baseOptions has RoundedVignetteBitmapDisplayer

// after
DisplayImageOptions plain = baseOptions.newBuilder().displayer(null).build();
imageLoader.displayImage(uri, nonViewAware, plain);
Defensive patterns

Strategy: type-guard

Validate before calling

if (aware instanceof ImageViewAware) {
    imageLoader.displayImage(uri, aware, vignetteOptions);
} else {
    imageLoader.displayImage(uri, aware, vignetteOptions.newBuilder().displayer(null).build());
}

Type guard

private static boolean isVignetteSafe(ImageAware aware, DisplayImageOptions opts) {
    return !(opts.getDisplayer() instanceof RoundedVignetteBitmapDisplayer)
            || aware instanceof ImageViewAware;
}

Prevention

When it happens

Trigger: Configuring options with .displayer(new RoundedVignetteBitmapDisplayer(radius, margin)) and invoking displayImage with NonViewAware or any custom ImageAware that does not extend ImageViewAware. Inheriting display options from a base class that includes the vignette displayer and reusing them for non-view loads.

Common situations: Central DisplayImageOptions constants shared across an app (image grid + background prefetch) where one path uses NonViewAware; refactoring from ImageView-only loading to generic ImageAware targets without stripping the displayer.

Related errors


AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14). Data as JSON: /api/errors/1b13cb26455e9b6c. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/nostra13/universalimageloader/core/display/RoundedVignetteBitmapDisplayer.java:47

 * Romain Guy's article</a>. It rounds images using custom drawable drawing. Original bitmap isn't changed.
 * <br />
 * <br />
 * If this implementation doesn't meet your needs then consider
 * <a href="https://github.com/vinc3m1/RoundedImageView">this project</a> for usage.
 *
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 * @since 1.9.1
 */
public class RoundedVignetteBitmapDisplayer extends RoundedBitmapDisplayer {

	public RoundedVignetteBitmapDisplayer(int cornerRadiusPixels, int marginPixels) {
		super(cornerRadiusPixels, marginPixels);
	}

	@Override
	public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
		if (!(imageAware instanceof ImageViewAware)) {
			throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected.");
		}

		imageAware.setImageDrawable(new RoundedVignetteDrawable(bitmap, cornerRadius, margin));
	}

	protected static class RoundedVignetteDrawable extends RoundedDrawable {

		RoundedVignetteDrawable(Bitmap bitmap, int cornerRadius, int margin) {
			super(bitmap, cornerRadius, margin);
		}

		@Override
		protected void onBoundsChange(Rect bounds) {
			super.onBoundsChange(bounds);
			RadialGradient vignette = new RadialGradient(
					mRect.centerX(), mRect.centerY() * 1.0f / 0.7f, mRect.centerX() * 1.3f,
					new int[]{0, 0, 0x7f000000}, new float[]{0.0f, 0.7f, 1.0f},
					Shader.TileMode.CLAMP);

View on GitHub (pinned to ba33ec64d0)