必须始终接通每个 WakeLock.release() 电话吗? android 棉绒警告

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

Android lint 使用 [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;
    }
}

第一次出现时给出警告

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

不过,并不是真的需要每次都释放,因为有超时。

将其包装在 try-catch 块中的默认解决方案,例如 android-wakelock-not-released-after-getactivenetworkinfo, or in , do not address the problems that led to using this approach, namely that the device can go back to sleep.

这是如何修复的?还是应该忽略它?

使用设备唤醒时执行的 try-catch 块包装任务

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();
            }
    });

正如@tyczj 所暗示的:

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

所以考虑警告,

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.

要删除这种情况下的警告,请使用

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

import android.annotation.SuppressLint;

确实,这似乎是一个被遗忘已久的问题。事实上,这个错误早在 2013 年 here 就已报告给 google,但似乎仍然存在。

正如一位评论者所说:

以下代码得到警告:

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

结果:

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

但是,如果您在方法中抛出异常,则不会报告任何警告:

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

要禁用此警告,请在您的应用程序 build.gradle 文件中执行此操作,以便于访问,而不是按照@user 的建议进行内联。

...
lintOptions {
        disable 'Wakelock'
}