Как бороться с (осиротевшими) WakeLocks?

Я думаю, что большинство из вас, по крайней мере, слышали о WakeLocks . Многие из вас уже испытали их — сознательно или нет. Некоторые могут знать, как обращаться с ними в целом, но лишь немногие знают, как обращаться с «более сложными кандидатами».

Для тех, кто не знает, хотя приведенная выше ссылка ведет к объяснению, краткое резюме: приложения могут запрашивать, WAKE_LOCKчтобы компонент устройства не «спал», чтобы они могли выполнять задачу, даже когда дисплей выключен. Это очень полезно в большинстве случаев (например, держать экран включенным во время навигации, поддерживать Wi-Fi активным для потоковой передачи музыки), но при неправильном использовании это приводит к разрядке аккумулятора в течение короткого времени (до 25% в час). .

В большинстве случаев легко определить источник (обычно приложение с плохим поведением) — я покажу это в ответе ниже, так как это может оказаться полезным для многих пользователей. Но что делать, если приложение, запросившее WakeLock, закрывается, не разблокировав его? Система Android не позаботится об этом . Конечно, перезагрузка решила бы проблему, но это не всегда (желательный) вариант.

Итак, с точки зрения пользователей (я не спрашиваю о решениях для разработки, а о том, как пользователь может с этим справиться):

Что может сделать *пользователь* , чтобы решить проблему и избежать дальнейшего разряда батареи?

Я предпочитаю ответы , не связанные с root (чтобы все пользователи могли извлечь из этого пользу). Тем не менее, «укоренившиеся решения» также полностью действительны и приветствуются.

У меня сложилось впечатление, что это верно только в том случае, если вы создали wakelock «неправильным» способом, используя /sys/power/wake_lock, но если вы сделали это «правильным» способом, используя PowerManager и PowerManager.WakeLock, обе службы будут удерживать настоящую wakelock и отпустите его, даже если ваш процесс был убит...
Согласно информации, которую я связал, это явно не так. Кто-то там сообщает, что проверил исходники ядра и не нашел ни намека на это. Подсказка для разработчиков: кажется, что «частичные wakelocks» могут быть запрошены timed , поэтому они автоматически истекают, когда таймер истечет, а запрос wakelock не будет обновлен. Это должен быть «безопасный способ», о котором вы говорите.

Ответы (4)

Как я могу сказать, что я затронут?

Это, наверное, первый вопрос к тем, кто не знаком с этой темой. С Gingerbread (Android 2.3) и более поздними версиями у вас есть встроенная служба, которая поможет вам разобраться: статистика батареи. Хотя производители, как правило, размещают его в разных местах, в основном его можно найти в разделе «Настройки» → «О телефоне» → «Аккумулятор » или аналогичном, и он показывает список приложений, которые использовали большую часть вашей батареи. Сверху небольшой график. Коснитесь этого, и вы попадете на экран, похожий на этот:

статистика батареи
Скриншот статистики батареи на Android 2.3

Я выбрал снимок экрана с одного из моих устройств, который иллюстрирует проблему. Глядя на две нижние синие полоски («Актив» = устройство не спит (активно), «Билдширм» = «Экран включен»), самая правая синяя полоса на «Активе» указывает на WakeLock: устройство оставалось занятым, несмотря на тот факт, что экран был выключен. Таким образом, мы можем быть уверены, что у нас есть WakeLock, но мы не можем сказать, кто его вызвал.

Если на вашем устройстве нет этого экрана (или полос внизу: я только что обнаружил, например, что LG Optimus 4X под управлением Android 4.0.3 обрезает эти полосы), вы можете найти их, например, с помощью GSam Battery Monitor :

Монитор батареи GSam
Аналогичная информация от GSam Battery Monitor — здесь упомянутые «синие полосы» желтые/оранжевые.

Что вызвало WakeLock?

К сожалению, на этот вопрос нельзя ответить с помощью предустановленных приложений (за исключением, может быть, некоторых пользовательских ПЗУ). Но есть инструменты, которые могут. Самый известный кандидат на это — BetterBatteryStats , который показывает нам причину в разделе частичных пробуждения :

BetterBatteryStats BetterBatteryStats2
Скриншоты из BetterBatteryStats

В первом примере 2 (взятом со страницы PlayStore приложения) событие, вызывающее большую часть WakeLocks, было желаемым: мы не хотим, чтобы воспроизведение останавливалось во время прослушивания музыки. Таким образом, второй пример 3 (взятый из реального случая на одном из моих устройств) может оказаться лучше: самые верхние 3 события вызваны одним и тем же приложением, которому требовался WakeLock для поддержания активной службы push-уведомлений IMAP.

В качестве альтернативы BetterBatteryStats ознакомьтесь с приложением Wakelock Detector , упомянутым в ответе UzumApps, с которым легче справиться, особенно для нетехнических специалистов:

Wakelock Detector: сведения о приложении Wakelock Detector: выберите процессы
Wakelock Detector -- Щелкните изображение, чтобы увеличить его. (Источник: Google Play )

Что может быть сделано?

Если дело так же ясно, как во втором примере в предыдущем разделе, то и действие совершенно очевидно — по крайней мере, в моем случае: мне не нужно получать немедленную информацию о прибытии почты; задержка в 30 минут абсолютно приемлема. Поэтому я зашел в почтовое приложение, отключил IMAP Push (см. также: Push Email ) и вместо этого переключился на 30-минутный интервал опроса. WakeLocks не исчезли полностью, но заметно уменьшились — заметно увеличилось время автономной работы.

Тогда есть случай, упомянутый в самом вопросе: приложение с плохим поведением не выпускает свой WakeLock. Сообщите разработчику о своих выводах и попросите исправить. Если он доставляет: проблема решена. Если нет: почти всегда есть альтернативное приложение.

Что, если это сама система Android?

Да, иногда это выглядит именно так: 98% и более потребляется какой-то службой Android. О, если это 98%, в большинстве случаев кандидат называется LocationManagerService . Плохой парень шпионит за нами? Не обязательно. В этом особом случае указанный «плохой парень» даже не виновен — по крайней мере, не напрямую. Вот еще одно приложение, слишком часто запрашивающее текущее местоположение. На сайте Setera.org есть отличная статья по этому поводу: Определение расхода батареи Android LocationManagerService . Чтобы дать аннотацию: он использует Androiddumpsysфункция (требуется root!) для создания дампа состояния системы и позволяет исследовать прослушиватели, установленные для службы LocationManagerService. При внимательном рассмотрении их конфигурации видно, что они постоянно "забивают" его информацией о местоположении (некоторые делают это постоянно, т.е. без перерыва). Поскольку идентификатор приложения указан рядом и в другом месте дампа даже вместе с техническим именем приложения, вы все равно можете идентифицировать его и предпринять соответствующие действия.

А как же НЛО?

К сожалению, есть такие: Приложения, которые зарегистрировали WakeLock, а затем вышли, не разблокировав его. Что осталось, так это *неиспользуемые гребаные устаревшие устройства* -- бесполезные WakeLocks. Таким образом, невозможно просто вывести приложение на передний план и перенастроить или заставить его выпустить свои WakeLocks.

Здесь единственное известное мне решение - это перезагрузка, и я хотел бы иметь лучшее решение. Конечно, если вы знаете виновное приложение, действия по его устранению такие же, как описано выше: сообщить разработчику, получить исправление или заменить приложение. А насчет избавления от текущего WakeLock? Может быть, кто-то еще может предложить лучшую альтернативу перезагрузке?

Есть ли рекомендуемые дополнительные чтения?

Конечно. Пока один, позже могу добавить еще:

Лучшее образование для разработчиков, чтобы сказать... «Выпускайте вейклоки, когда вы закончите с ними, и убирайте за собой»?
Проголосуйте за ваш, как всегда, ошеломляющий ответ!!! Тебе это никогда не надоедает? :D
Конечно, но посмотрите на мой вопрос: я явно НЕ спрашиваю о стороне разработчика, а с точки зрения пользователя . Может быть, мне нужно сделать это более очевидным;)
Скучающий? Может кто-нибудь объяснить, на что это похоже? XD Нет, у меня всегда что-то на уме. Если я чувствую, что это достаточно хорошо, я даже спрашиваю об этом здесь (см. мой профиль: я не часто спрашиваю), хотя у меня может быть (частичный) ответ. Отзывы здесь всегда освежают, если вопрос того стоит :)
Если у меня будет время на этих выходных, я покопаюсь под капотом, чтобы посмотреть, есть ли механизм, позволяющий загружать ядро ​​из потерянных вейклоков.... ;)
Пожалуйста, сделай! И сообщайте о своих выводах! У меня только что была описанная проблема с «осиротевшими» WakeLocks. Поковырявшись в течение часа, я не продвинулся дальше, чем увидел, что это LocationManagerService . Зарегистрировался для получения обновлений, все 0сек (sic!) были в настройках Android (=:-0). Я вышел из него, остановил, убил в командной строке... нет способа избавиться от блокировок. WTF настройки там делал? Перезагрузка, конечно, решила проблему, но разве это WindowsPhone, который нужно перезагружать два раза в день?
@ t0mm13b, поскольку эти выходные уже давно прошли: вы нашли что-нибудь полезное в своем сеансе c64 (заглянуть и ткнуть)?

Короче говоря, это очень хороший вопрос, но, боюсь, он требует большего, чем просто информирование конечного пользователя!

Перепроектируйте ядро, чтобы устранить блокировку пробуждения и использовать более тщательный и эффективный способ управления этим принципом, тем самым продлевая срок службы батареи.

К сожалению, де-факто это было принято как решение для включения «управления питанием», несмотря на то, что оно также не совсем эффективно! Была обширная дискуссия о wakelocks (с Грегом Кроа Хартманом — гуру Linux по разработке драйверов — я ищу точную ссылку), другие сайты, такие как LWN.net , и еще одна статья, объясненная на том же сайте здесь . Это была статья, на которую Грег Кроа Хартман сослался в этом блоге , в которой он, кажется, согласен с альтернативным решением, предложенным Рафаэлем Дж. Высоцки , и многое задокументировал о потенциальной альтернативе. Не уверен, что это действительно так в более современном ядре v3.xx.

Плохо спроектированные приложения могут и часто запрашивают пробуждения, такие как сохранение экрана включенным, но на самом деле в этом сценарии для удержания экрана есть более эффективный способ сделать это:

getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);

В то время как стремление не допускать жаргона и т. д. для конечного пользователя, на самом деле суть проблемы сводится к коду ядра в том, как управляются wakelocks.

Вот краткое изложение на XDA о том, что такое wakelocks для непосвященных. Используя BetterBatteryStats , можно было точно увидеть, какой процесс разряжает батарею, вики размещена на github и доступна на рынке здесь .

Забавно, что вы указываете на ту же ветку XDA, о которой я упоминал. Я согласен с вами в том, что система должна проявлять больше заботы (например, сбрасывая WakeLocks, запрошенные приложениями, которые больше не работают). И что разработчикам следует уделять больше внимания кодированию (явно выпуская их в соответствующих состояниях жизненного цикла). Но это не помогает нам, пользователям , знать . Я надеюсь, что мой ответ дает некоторое представление о том, что может сделать пользователь, и что один из вас, «технарей», может заполнить оставшийся пробел!

Проверьте Wakelock Detector: XDA-Developers / Google Play :

Детектор вейклоков группирует вейклоки приложения в один расширяемый вид для лучшего просмотра. И он показывает, какие приложения запущены. И в расширенном представлении приложения есть кнопки информации об удалении удаления.

Wakelock Detector: сведения о приложении Wakelock Detector: выберите процессы
Нажмите на изображение, чтобы увеличить. (Источник: Google Play )

Раскрытие информации: я являюсь одним из ответственных разработчиков этого приложения. Еще четыре друга работают со мной над этим проектом в качестве хобби.

Спасибо! Это действительно ценная информация. Не могли бы вы добавить к своему ответу больше деталей, например, что делает его таким особенным? Я бы добавил несколько скриншотов тогда. Пока это не сделано: вот ссылка Playstore на приложение ...
Спасибо за подробности! Я объединил их в ваш ответ, надеюсь, вы не возражаете :) Вопрос понимания: скажем, приложение запрашивает местоположение с интервалом «0 секунд». Это приведет к тому, что LocationService будет блокировать устройство. Будет ли Wake Lock Detector показывать ответственное приложение как реальную причину — или LocationService , поскольку оно не является частью этого пакета приложений?
Ответ на ваш вопрос «нет», потому что детектор wakelock группирует wakelocks, принадлежащие одному и тому же имени пакета приложения. Поскольку служба определения местоположения принадлежит ОС Android, решением будет проверка разрешений пользователя приложения.
Большое спасибо! Я надеялся найти простое решение вопроса «Что, если это сама система Android?» часть. Кажется, такой вещи нет, но если это возможно, было бы неплохо интегрироваться с WLD :)
Спасибо за ваше мнение, я учту его и буду работать над этим. ВД хорошо выглядит!!! :)

Пара способов, которые помогут пользователям нерутированных устройств

  1. Увидев, что @Uzumapps, один из разработчиков приложения, опубликовал решение с использованием Wakelock Detector ( WLD ), я удивлен, что он не сообщил об использовании приложения, которое также можно использовать без рута, под названием Wakelock Detector Light ! Я обнаружил это в поисках решения для моего нового устройства (без рута).

Это недавняя разработка, и поэтому она публикуется для пользователей устройств без рута. Протестировано как работающее на Moto X Play (Android 6.0.1)

  • Загрузите WLD из магазина Play по ссылке выше.

  • Руководство по использованию WLD здесь

  • Инструкция для нерутированных устройств здесь . В нем есть все детали, но резюмирую:

    мощность dumpsys оболочки adb | grep -i partial_wake_lock

Примечание. Я не смог заставить работать второй метод, я бы приветствовал решение по редактированию, чтобы заставить его работать для неподкованных парней, таких как я .