didi/DoKit · error · IllegalStateException

Memory cache already set.

Error message

Memory cache already set.

What it means

DokitPicasso.Builder.memoryCache() throws IllegalStateException when a Cache has already been assigned. The builder treats the memory cache as single-assignment so a misconfigured pipeline fails loudly instead of quietly swapping caches.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java:753

     */
    public Builder executor(ExecutorService executorService) {
      if (executorService == null) {
        throw new IllegalArgumentException("Executor service must not be null.");
      }
      if (this.service != null) {
        throw new IllegalStateException("Executor service already set.");
      }
      this.service = executorService;
      return this;
    }

    /** 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;
    }

    /**

View on GitHub (pinned to 626827cddb)

Solutions

  1. Keep exactly one memoryCache() call per Builder
  2. Move cache selection into a single helper that decides which cache to install
  3. Rebuild from a new Builder when the full configuration must change

Example fix

// before
builder.memoryCache(new LruCache(1024));
builder.memoryCache(new LruCache(context)); // IllegalStateException

// after
builder.memoryCache(new LruCache(context));
Defensive patterns

Strategy: validation

Validate before calling

// choose the cache first, then a single memoryCache() call
Cache chosen = useDefault ? new LruCache(context) : new LruCache(customBytes);
builder.memoryCache(chosen);

Try / catch

try { builder.memoryCache(c); } catch (IllegalStateException e) { if (!e.getMessage().contains("Memory cache already set")) throw e; }

Prevention

When it happens

Trigger: Calling builder.memoryCache(...) a second time on the same Builder, e.g. a default LruCache set in shared code and a tuned cache set later.

Common situations: Two init layers (library default + app override) both configuring the cache; copy-pasted setup blocks after a cache-size refactor.

Related errors


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