didi/DoKit · error · IllegalArgumentException

remoteViews must not be null.

Error message

remoteViews must not be null.

What it means

Thrown by RequestCreator.into(RemoteViews, int, int[]) (the app-widget variant) when the remoteViews argument is null. The action (AppWidgetAction) needs a concrete RemoteViews instance to apply the loaded bitmap into every widget instance, so a null one is rejected immediately with an IllegalArgumentException. This is a plain argument-contract failure, not a state conflict.

Source

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

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

        RemoteViewsAction action =
                new NotificationAction(picasso, request, remoteViews, viewId, notificationId, notification,
                        memoryPolicy, networkPolicy, key, tag, errorResId);

        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);

View on GitHub (pinned to 626827cddb)

Solutions

  1. Construct the RemoteViews(context.getPackageName(), R.layout.widget_layout) before calling into().
  2. Guard the call: only invoke into() when the RemoteViews was successfully created.
  3. Check that the widget layout resource exists and the correct package name is used, since RemoteViews construction itself throws on bad resources.

Example fix

// before
RemoteViews views = maybeBuildViews(); // may return null
picasso.load(url).into(views, R.id.widget_icon, appWidgetIds);

// after
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
picasso.load(url).into(views, R.id.widget_icon, appWidgetIds);
Defensive patterns

Strategy: validation

Validate before calling

if (remoteViews == null) {
    remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
}
picasso.load(url).into(remoteViews, viewId, appWidgetIds);

Type guard

private boolean isValidRemoteViewsTarget(RemoteViews rv, int[] ids) {
    return rv != null && ids != null && ids.length > 0;
}

Prevention

When it happens

Trigger: Calling into(null, viewId, appWidgetIds), or passing a RemoteViews variable that was never constructed / was nulled after a failed build, into the widget variant of into().

Common situations: Building RemoteViews conditionally (e.g. only for certain widget sizes) and passing the variable unconditionally; copy-paste from the notification variant where the wrong local variable is passed; widget provider code paths where the layout inflation was skipped.

Related errors


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