Tencent/matrix · error · RuntimeException

Use #onStateChanged(BatteryState, String) instead

Error message

Use #onStateChanged(BatteryState, String) instead

What it means

DefaultListenerImpl deliberately overrides onStateChanged(String) to throw RuntimeException unconditionally, steering callers to the newer onStateChanged(BatteryState, String) callback. The raw-string variant is deprecated because it loses typed battery-state information.

Solutions

  1. Override onStateChanged(BatteryState batteryState, String event) in your listener subclass and put handling logic there.
  2. Remove any explicit calls to onStateChanged(String) in listener code.
  3. Migrate custom listeners to implement the current BatteryEventDelegate listener interface directly instead of extending DefaultListenerImpl.

Example fix

// before
new BatteryEventDelegate.DefaultListenerImpl(true) {
    // no override: base throws on callback
}

// after
new BatteryEventDelegate.DefaultListenerImpl(true) {
    @Override
    public boolean onStateChanged(BatteryState state, String event) {
        return handle(state, event);
    }
}
Defensive patterns

Strategy: try-catch

Prevention

When it happens

Trigger: Registering a listener object whose class extends DefaultListenerImpl (or uses it as a base) and relies on the inherited string-based onStateChanged(String) without overriding it — the delegate will call the base implementation and throw.

Common situations: Upgrading the battery-canary library where the callback signature changed from String to (BatteryState, String); copying an old listener implementation that fails to override the new method.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

             * @param isLowBattery {@link Intent#ACTION_BATTERY_LOW}, {@link Intent#ACTION_BATTERY_OKAY}
             * @return return true if your listening is done, thus we remove your listener
             */
            @UiThread
            boolean onBatteryStateChanged(BatteryState batteryState, boolean isLowBattery);
        }

        @SuppressWarnings("unused")
        class DefaultListenerImpl implements ExListener {

            final boolean mKeepAlive;

            public DefaultListenerImpl(boolean keepAlive) {
                mKeepAlive = keepAlive;
            }

            @Override
            public boolean onStateChanged(String event) {
                throw new RuntimeException("Use #onStateChanged(BatteryState, String) instead");
            }

            @Override
            public boolean onAppLowEnergy(BatteryState batteryState, long backgroundMillis) {
                return !mKeepAlive;
            }

            @Override
            public boolean onStateChanged(BatteryState batteryState, String event) {
                return !mKeepAlive;
            }

            @Override
            public boolean onBatteryTemperatureChanged(BatteryState batteryState, int temperature) {
                return !mKeepAlive;
            }

            @Override

View on GitHub (pinned to 3b8293bd65)