didi/DoKit · error · IllegalStateException
Listener already set.
Error message
Listener already set.
What it means
DokitPicasso.Builder.listener() throws IllegalStateException when a Listener has already been set. The listener slot is single-assignment like the other builder components, so configuring it twice fails immediately.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java:765
/** Specify the memory cache used for the most recent images. */
public Builder memoryCache(Cache memoryCache) {
if (memoryCache == null) {
throw new IllegalArgumentException("Memory cache must not be null.");
}
if (this.cache != null) {
throw new IllegalStateException("Memory cache already set.");
}
this.cache = memoryCache;
return this;
}
/** Specify a listener for interesting events. */
public Builder listener(Listener listener) {
if (listener == null) {
throw new IllegalArgumentException("Listener must not be null.");
}
if (this.listener != null) {
throw new IllegalStateException("Listener already set.");
}
this.listener = listener;
return this;
}
/**
* Specify a transformer for all incoming requests.
* <p>
* <b>NOTE:</b> This is a beta feature. The API is subject to change in a backwards incompatible
* way at any time.
*/
public Builder requestTransformer(RequestTransformer transformer) {
if (transformer == null) {
throw new IllegalArgumentException("Transformer must not be null.");
}
if (this.transformer != null) {
throw new IllegalStateException("Transformer already set.");
}View on GitHub (pinned to 626827cddb)
Solutions
- Register only one Listener and route events from it to all consumers
- If multiple observers are needed, create a composite listener that fans out and register it once
- Remove the duplicate listener() call
Example fix
// before
builder.listener(baseListener);
builder.listener(appListener); // IllegalStateException
// after
class CompositeListener implements DokitPicasso.Listener {
...delegate to baseListener and appListener...
}
builder.listener(new CompositeListener()); Defensive patterns
Strategy: validation
Validate before calling
class Composite implements DokitPicasso.Listener { public void onImageLoadFailed(DokitPicasso p, Uri u, Exception e) { a.onImageLoadFailed(p,u,e); b.onImageLoadFailed(p,u,e); } }
builder.listener(new Composite()); // registered once Try / catch
try { builder.listener(l); } catch (IllegalStateException e) { if (!e.getMessage().contains("Listener already set")) throw e; } Prevention
- Use one composite listener when multiple subsystems need failure callbacks
When it happens
Trigger: Calling builder.listener(...) twice, e.g. a base SDK init installs a listener and app code installs another one for its own error reporting.
Common situations: Layered initialization (framework + app) that both want load-failure callbacks; merging two setup code paths without deduplicating the listener call.
Related errors
- Downloader already set.
- Executor service already set.
- Memory cache already set.
- Transformer already set.
- RequestHandler already registered.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/56c9d7b4a4c306f5.
Report an issue: GitHub.