didi/DoKit · critical · IllegalStateException
Picasso instance already shut down. Cannot submit new reques
Error message
Picasso instance already shut down. Cannot submit new requests.
What it means
Thrown by the RequestCreator constructor when the DokitPicasso instance it is asked to build requests for has been shut down. Picasso.shutdown() releases its cache, dispatcher, and workers; the instance is terminal, and every new request (load(...)) is rejected with IllegalStateException.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/RequestCreator.java:73
private static final AtomicInteger nextId = new AtomicInteger();
private final DokitPicasso picasso;
private final Request.Builder data;
private boolean noFade;
private boolean deferred;
private boolean setPlaceholder = true;
private int placeholderResId;
private int errorResId;
private int memoryPolicy;
private int networkPolicy;
private Drawable placeholderDrawable;
private Drawable errorDrawable;
private Object tag;
RequestCreator(DokitPicasso picasso, Uri uri, int resourceId) {
if (picasso.shutdown) {
throw new IllegalStateException(
"Picasso instance already shut down. Cannot submit new requests.");
}
this.picasso = picasso;
this.data = new Request.Builder(uri, resourceId, picasso.defaultBitmapConfig);
}
RequestCreator() {
this.picasso = null;
this.data = new Request.Builder(null, 0, null);
}
/**
* Explicitly opt-out to having a placeholder set when calling {@code into}.
* <p>
* By default, Picasso will either set a supplied placeholder or clear the target
* {@link ImageView} in order to ensure behavior in situations where views are recycled. This
* method will prevent that behavior and retain any already set image.
*/View on GitHub (pinned to 626827cddb)
Solutions
- Do not reuse a Picasso instance after calling shutdown(); re-obtain the instance from its provider/factory for new requests.
- Remove or defer the shutdown() call if the instance must keep serving requests.
- Cancel in-flight work and drain threads before shutdown so late submissions cannot occur.
Example fix
// before
static DokitPicasso PICASSO = DokitPicasso.get(context);
void onTeardown() { PICASSO.shutdown(); }
void later() { PICASSO.load(url).into(view); } // throws
// after
void onTeardown() { PICASSO.shutdown(); PICASSO = null; }
void later() { if (PICASSO == null) PICASSO = DokitPicasso.get(context); PICASSO.load(url).into(view); } Defensive patterns
Strategy: validation
Validate before calling
if (picasso.shutdown) {
picasso = DokitPicasso.get(context); // or your provider's fresh instance
}
picasso.load(url).into(view); Try / catch
try {
picasso.load(url).into(view);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("shut down")) {
picasso = DokitPicasso.get(context); // re-obtain and retry once
picasso.load(url).into(view);
} else { throw e; }
} Prevention
- Null out references to a Picasso instance when you shut it down.
- Never call shutdown() from low-memory handlers while requests may still be created.
- Route all loads through one accessor that re-creates the instance after shutdown.
When it happens
Trigger: Calling picasso.load(...) (or new RequestCreator(picasso, ...)) after picasso.shutdown() ran on that same instance.
Common situations: Keeping the Picasso instance in a static/singleton field that outlives shutdown triggered by DoKit teardown, low-memory handling, or app-module reload; background threads racing a shutdown; tests that shut down between cases but reuse the instance.
Related errors
- Default singleton instance cannot be shutdown.
- Singleton instance already exists.
- buildAndInstall() should only be called once.
- Unrecognized type of request: " + request
- Failed to decode stream.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/8a09a913407b6ff0.
Report an issue: GitHub.