Tencent/matrix · error · IllegalStateException

Call #init() first!

Error message

Call #init() first!

What it means

BatteryEventDelegate.getInstance() uses double-checked locking and throws IllegalStateException if sInstance is null, meaning BatteryEventDelegate.init() was never called. The delegate is a singleton that requires explicit initialization before any accessor can be used.

Solutions

  1. Call BatteryEventDelegate.init(applicationContext) (ideally in Application.onCreate) before any getInstance() call.
  2. Guard access: only call getInstance() after verifying init completed, e.g. keep a boolean flag set post-init.
  3. In tests, invoke init() in @Before setup or mock the delegate instead of the singleton.

Example fix

// before
BatteryEventDelegate delegate = BatteryEventDelegate.getInstance(); // IllegalStateException

// after
// in MyApplication.onCreate()
BatteryEventDelegate.init(getApplication());
BatteryEventDelegate delegate = BatteryEventDelegate.getInstance();
Defensive patterns

Strategy: try-catch

Try / catch

try {
    BatteryEventDelegate d = BatteryEventDelegate.getInstance();
    // use d
} catch (IllegalStateException e) {
    BatteryEventDelegate.init(application); // lazy init then retry
    BatteryEventDelegate d = BatteryEventDelegate.getInstance();
}

Prevention

When it happens

Trigger: Calling BatteryEventDelegate.getInstance() before any call to BatteryEventDelegate.init(context, ...) — e.g. during early Application startup ordering, or after init failed silently.

Common situations: Accessing the delegate from a component (Activity/Service/ContentProvider) that runs before Application.onCreate init; calling getInstance() in unit tests without initializing the singleton; init() throwing earlier so sInstance was never assigned.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/53951183681fa144. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/BatteryEventDelegate.java:80

            }
        }
    }

    public static void init(Application application) {
        if (sInstance == null) {
            synchronized (TAG) {
                if (sInstance == null) {
                    sInstance = new BatteryEventDelegate(application);
                }
            }
        }
    }

    public static BatteryEventDelegate getInstance() {
        if (sInstance == null) {
            synchronized (TAG) {
                if (sInstance == null) {
                    throw new IllegalStateException("Call #init() first!");
                }
            }
        }
        return sInstance;
    }

    final Context mContext;
    final List<Listener> mListenerList = new LinkedList<>();
    final Handler mUiHandler = new Handler(Looper.getMainLooper());
    final BackgroundTask mAppLowEnergyTask = new BackgroundTask();
    boolean sIsForeground = true;
    long mLastBatteryPowerPct;
    long mLastBatteryTemp;

    @Nullable
    BatteryMonitorCore mCore;

View on GitHub (pinned to 3b8293bd65)