Должен каждый блокировкой.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;
    }
}

Он дает предупреждение для первого появления

[Линт] [...] / WakeLocker.java: предупреждение: вызов release () не всегда достигается [Wakelock]

Тем не менее, на самом деле не нужно выпускать каждый раз, так как есть тайм-аут.

Стандартное решение обертывания этого в try-catch-блок, как, например, в android-wakelock-not-released-after-getactivenetworkinfo , или в ответе @rainash ниже , не рассматривайте проблемы, которые привели к использованию этого подхода, а именно что устройство может снова заснуть.

Как это исправить? Или его следует игнорировать?

3 2

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

Чтобы отключить это предупреждение, лучше сделать это в файле apps build.gradle для легкого доступа, а не встроенным, как предлагает @user.

...
lintOptions {
        disable 'Wakelock'
}

Использовать попробовать-поймать задач блока обертывание выполняется, когда устройство бодрствует

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;