Использование блокировки пробуждения может ухудшить производительность устройства. Если вам необходимо использовать блокировку пробуждения, важно делать это правильно. В этом документе описаны некоторые рекомендации, которые помогут вам избежать распространенных ошибок при использовании блокировки пробуждения.
Правильно назовите блокировку пробуждения.
Мы рекомендуем указывать имя вашего пакета, класса или метода в теге wakelock. Таким образом, в случае ошибки будет проще найти место в исходном коде, где была создана блокировка пробуждения. Вот еще несколько советов:
- В имени не следует указывать никакую личную информацию, например, адрес электронной почты. Если устройство обнаружит личную информацию в теге блокировки пробуждения, оно запишет в лог
_UNKNOWNвместо указанного вами тега. - Не пытайтесь получить имя класса или метода программным способом, например, вызывая
getName(). Если вы попытаетесь получить имя программным способом, оно может быть зашифровано такими инструментами, как Proguard. Вместо этого используйте жестко заданную строку. - Не добавляйте счетчик или уникальные идентификаторы к тегам блокировки пробуждения. Код, создающий блокировку пробуждения, должен использовать один и тот же тег при каждом запуске. Такая практика позволяет системе суммировать использование блокировки пробуждения каждым методом.
Убедитесь, что ваше приложение отображается на переднем плане.
Пока активна блокировка пробуждения, устройство потребляет энергию. Пользователь устройства должен знать об этом. Поэтому, если вы используете блокировку пробуждения, следует отображать пользователю какое-либо уведомление. На практике это означает, что следует получать и удерживать блокировку пробуждения в фоновой службе . Фоновые службы обязаны отображать уведомление.
Если использование фоновой службы не подходит для вашего приложения, вам, вероятно, не следует использовать и блокировку пробуждения. См. документацию «Выбор подходящего API для поддержания активности устройства» для получения информации о других способах выполнения задач, когда ваше приложение не находится на переднем плане.
Придерживайтесь простой логики.
Убедитесь, что логика получения и снятия блокировок пробуждения максимально проста. Когда ваша логика блокировки пробуждения связана со сложными конечными автоматами, таймаутами, пулами исполнителей или событиями обратного вызова, любая незначительная ошибка в этой логике может привести к тому, что блокировка пробуждения будет удерживаться дольше, чем ожидалось. Такие ошибки трудно диагностировать и отлаживать.
Убедитесь, что блокировка пробуждения всегда снимается.
При использовании блокировки пробуждения необходимо убедиться, что каждая полученная блокировка пробуждения корректно снимается. Это не всегда так просто, как кажется. Например, в следующем коде есть проблема:
Котлин
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
acquire()
doTheWork() // can potentially throw MyException
release() // does not run if an exception is thrown
}
}
Java
void doSomethingAndRelease() throws MyException {
wakeLock.acquire();
doTheWork(); // can potentially throw MyException
wakeLock.release(); // does not run if an exception is thrown
}
Проблема здесь в том, что метод doTheWork() может сгенерировать исключение MyException . В этом случае метод doSomethingAndRelease() распространяет исключение дальше, и вызов release() никогда не достигает цели. В результате блокировка пробуждения захватывается, но не освобождается, что очень плохо.
В исправленном коде метод doSomethingAndRelease() гарантирует снятие блокировки пробуждения даже в случае возникновения исключения:
Котлин
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
try {
acquire()
doTheWork()
} finally {
release()
}
}
}
Java
void doSomethingAndRelease() throws MyException {
try {
wakeLock.acquire();
doTheWork();
} finally {
wakeLock.release();
}
}