简体   繁体   中英

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?

use try-catch block wrap task you execute when device awake

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    final WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "tag");
    wakeLock.acquire();
            try {
                do something
            } finally {
                wakeLock.release();
            }
    });

As @tyczj hinted:

[Lint] also flags issues that may or may not be a problem depending on the context.

So think about the warning, and

If you've manually verified that an issue is not a problem, you may want to mark the issue as verified such that lint does not keep pointing it out.

To remove the warning in this case, use

@SuppressLint("Wakelock")
public static void acquire(Context ctx, long timeout) {

with

import android.annotation.SuppressLint;

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'
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM