每个WakeLock.release()调用是否必须始终到达?Android Lint警告

3

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: 警告:release()调用并不总是被执行到 [Wakelock]

然而,它并不真正需要每次都被释放,因为有一个超时时间。

默认的解决方案是将其包装在一个 try-catch 块中,例如在 android-wakelock-not-released-after-getactivenetworkinfo 或者在下面 @rainash 的回答 中,但这并没有解决使用这种方法所遇到的问题,即设备可能会重新进入睡眠状态

如何解决这个问题?还是应该忽略它?


1
你需要做什么?你不必做任何事情,这只是一个警告。 - tyczj
3个回答

3

在设备唤醒时,使用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();
            }
    });

上面的解决方案是针对设备收到警报但不总是立即响应的情况,因为超时时间过快,请参见https://dev59.com/zGw15IYBdhLWcg3wCnUn。 - serv-inc
@user1587329,我不知道你的评论在说什么,我之前也遇到过这个警告。如果你执行的任务在唤醒设备时抛出异常,.release() 并不总是会被执行到。 - rainash
总结链接内容:有时候你需要一个仅仅获取唤醒锁的小类,因为否则当处理程序加载时,你的设备可能会进入睡眠状态。我曾经遇到过这个问题。你能提出一个解决方案来解决这个主要问题并回答这个次要的lint问题吗? - serv-inc
因为努力值得赞赏 ;-)(是的,这条评论不是真正的评论) - serv-inc
我们可以在单独的函数中“释放”wakelock吗?还是必须与“获取”在同一调用点上? - IgorGanapolsky

2

事实上,这似乎是一个被长期遗忘的问题。事实上,这个错误在2013年就已经报告给了谷歌 (在此处),但看起来仍然存在。

正如一位评论者所说:

以下代码会出现警告:

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

结果显示:

release()调用并非总是被执行(通过异常流程)

然而,如果您在方法中抛出异常,将不会报告警告:

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

为了禁用此警告,建议您在应用程序的build.gradle文件中进行设置,以便更方便地访问,而不是像@user建议的那样内联设置。
...
lintOptions {
        disable 'Wakelock'
}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接