androidandroid-wake-lockandroid-lint

Must every WakeLock.release() call always be reached? android lint warning


Android lint warns on the following with [Wakelock]:

public static void acquire(Context ctx, long timeout) {
    if (wakeLock != null) {
        wakeLock.release();
    }

    PowerManager powerManager
        = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                    PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.ON_AFTER_RELEASE, 
                    Common.TAG);
    wakeLock.setReferenceCounted(false);

    if ( timeout <= 0 ) {
        wakeLock.acquire();
    } else {
        wakeLock.acquire(timeout);
    }
}

public static synchronized void release() {
    if ( wakeLock != null ) {
        if ( wakeLock.isHeld() ) {
            wakeLock.release(); 
        }
        wakeLock = null;
    }
}

It gives the warning for the first occurrence

[lint] [...]/WakeLocker.java: Warning: The release() call is not always reached [Wakelock]

Yet, it does not really need to be released every time, as there is a timeout.

The default solution of wrapping this in a try-catch-block, as for example in android-wakelock-not-released-after-getactivenetworkinfo, or in @rainash's answer below, do not address the problems that led to using this approach, namely that the device can go back to sleep.

How is this fixed? Or should it be ignored?


Solution

  • Indeed this seems to be a long forgotten problem. In fact this bug was reported to google already back in 2013 here, but seems to still be there.

    As one commenter states:

    The following code get the warning:

    try {
        wakeLock.acquire();
        ...
    } catch (Exception e) {
        ...
    } finally {
        wakeLock.release();
    }
    

    Results in:

    The release() call is not always reached (via exceptional flow)

    However, if you throw the Exception in a method, no warning is reported:

    private void makeMistake() throws Exception {
        throw new Exception();
        ...
        try {
            wakeLock.acquire();
            makeMistake();
        } catch (Exception e) {
        ...
        } finally {
            wakeLock.release();
        }
    }
    

    To disable this warning, rather do it in your apps build.gradle file, for easy access, rather than inline as suggested by @user.

    ...
    lintOptions {
            disable 'Wakelock'
    }