didi/DoKit · error · IllegalStateException

Fit cannot be used with remote views.

Error message

Fit cannot be used with remote views.

What it means

Thrown by RequestCreator.into(RemoteViews, int, int[]) (app-widget variant) when the request was built with fit(). fit() defers sizing to an ImageView's on-layout measurement; app-widget RemoteViews are inflated in the launcher process, so there is no view in this process to measure and the deferred request can never be sized. The library throws IllegalStateException instead of dead-locking the request.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/RequestCreator.java:596

        performRemoteViewInto(action);
    }

    /**
     * Asynchronously fulfills the request into the specified {@link RemoteViews} object with the
     * given {@code viewId}. This is used for loading bitmaps into all instances of a widget.
     */
    public void into(RemoteViews remoteViews, int viewId, int[] appWidgetIds) {
        long started = System.nanoTime();

        if (remoteViews == null) {
            throw new IllegalArgumentException("remoteViews must not be null.");
        }
        if (appWidgetIds == null) {
            throw new IllegalArgumentException("appWidgetIds must not be null.");
        }
        if (deferred) {
            throw new IllegalStateException("Fit cannot be used with remote views.");
        }
        if (placeholderDrawable != null || placeholderResId != 0 || errorDrawable != null) {
            throw new IllegalArgumentException(
                    "Cannot use placeholder or error drawables with remote views.");
        }

        Request request = createRequest(started);
        String key = createKey(request, new StringBuilder()); // Non-main thread needs own builder.

        RemoteViewsAction action =
                new AppWidgetAction(picasso, request, remoteViews, viewId, appWidgetIds, memoryPolicy,
                        networkPolicy, key, tag, errorResId);

        performRemoteViewInto(action);
    }

    /**
     * Asynchronously fulfills the request into the specified {@link ImageView}.

View on GitHub (pinned to 626827cddb)

Solutions

  1. Remove .fit() from the request used for widget loads.
  2. Size explicitly with .resize(w, h) — widget cells have known dp dimensions, e.g. resizeDimen(R.dimen.widget_icon, R.dimen.widget_icon).
  3. Maintain separate builder methods for widget vs. in-app targets so fit() never leaks into the widget path.

Example fix

// before
picasso.load(url).fit().into(views, R.id.widget_icon, appWidgetIds);

// after
picasso.load(url).resizeDimen(R.dimen.widget_icon, R.dimen.widget_icon).into(views, R.id.widget_icon, appWidgetIds);
Defensive patterns

Strategy: validation

Validate before calling

// Widget helper: explicit size, no fit()
public void loadWidgetImage(Picasso p, String url, RemoteViews views, int viewId, int[] ids) {
    p.load(url).resizeDimen(R.dimen.widget_icon, R.dimen.widget_icon)
     .into(views, viewId, ids);
}

Try / catch

Not applicable — deterministic misuse; removing fit() is the only correct fix.

Prevention

When it happens

Trigger: Chaining .fit() with into(remoteViews, viewId, appWidgetIds) — the deferred flag set by fit() triggers the throw in the widget path.

Common situations: Reusing the same request builder helper for both activity ImageViews and widget loads; porting list-row loading code (where fit() is idiomatic) into a home-screen widget provider.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/f1a5260ead66abde. Report an issue: GitHub.