Должен ли каждый вызов WakeLock.release() быть всегда достигнут? Android Lint предупреждение
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
-block, как, например, в /questions/37257180/android-wakelock-ne-vyipuschen-posle-getactivenetworkinfo или в ответе @rainash ниже, не решает проблемы, которые привели к использованию этого подхода, а именно, что устройство может вернуться в спящий режим.
Как это исправить? Или это следует игнорировать?
3 ответа
Действительно, это кажется давно забытой проблемой. На самом деле эта ошибка была сообщена Google еще в 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'
}
Использовать задачу try-catch block wrap, которую вы выполняете, когда устройство активируется
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] также помечает проблемы, которые могут или не могут быть проблемой в зависимости от контекста.
Так что подумайте о предупреждении, и
Чтобы удалить предупреждение в этом случае, используйте
@SuppressLint("Wakelock")
public static void acquire(Context ctx, long timeout) {
с
import android.annotation.SuppressLint;