Должен ли каждый вызов 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;
Другие вопросы по тегам