Проблема
Я давно занимаюсь разработкой под Android. Одна из разработанных мной программ интенсивно использует WakeLocks . Обычно это прекрасно (часто в течение нескольких дней или недель, требование программы), но очень редко я замечаю в этом коде своеобразное поведение:
acquireWakeLock(wakeLockManager)
// Preconditions
assertFalse("Wake lock already acquired.", hasWakeLock());
assertNotNull("Wake lock manager not provided.", wakeLockManager);
// Acquire a wake lock.
wakeLock = wakeLockManager.newPartialWakeLock(DEBUG_TAG);
wakeLock.acquire();
// Postconditions
assertTrue("Wake Lock should be held!", hasWakeLock());
Где hasWakeLock()
просто возвращает результат (wakeLock != null && wakeLock.isHeld())
, а wakeLockManager.newPartialWakeLock(DEBUG_TAG)
инкапсулирует стандартный код «получить PowerManager и затем вернуть блокировку при активации». В целях тестирования утверждениями assert являются методы JUnit assert, поэтому я думаю, что мы можем предположить, что они правильные.
Проблема с кодом заключается в следующем: окончательное утверждение - assertTrue(hasWakeLock())
- похоже, терпит неудачу каждые несколько недель без особых объяснений. Это означает, что у меня есть три возможные проблемы: (1) блокировка пробуждения вообще не извлекается из PowerManager (2), что у меня возникает проблема параллелизма, которая в редких случаях вступает в силу непосредственно перед постусловием, но после вызова acquire()
или что (3) acquire()
иногда неисправен.
Исследование проблемы
Как указано выше, у меня есть три потенциальных проблемы, которые могут возникать и которые я расследую:
Гипотеза 1: Wake Lock не возвращается :
Если бы это было так, я бы увидел исключение нулевого указателя. Этого не может быть.
Гипотеза 2: У меня проблема с параллелизмом :
Только что проведенная формальная проверка всех мест, связанных с приобретением и выпуском wakeLock
, убедительно заставляет меня поверить, что это не так. В случае, если мое доказательство неверно, у меня может возникнуть проблема с параллелизмом, но тогда это действительно коварно и трудно найти.
Гипотеза 3: WakeLock.acquire () неисправен, и несмотря на то, что в документации сказано , иногда он может не получить блокировку :
Мне не нравится эта гипотеза, потому что со всеми пользователями Android наш там кто-то кроме меня, должно быть, уже заметил это, и это почти всегда код разработчика, а не код библиотеки или ОС, то есть неисправна. С другой стороны, произошли странные вещи, и это может быть настоящая ошибка Android, хотя и редко встречающаяся. Если эта гипотеза верна, то acqu () просто не получает блокировку следа, и это объясняет поведение, которое я вижу.
Итак, StackOverflow, что может быть причиной этой проблемы? Что вы думаете не так? Я что-то упускаю из виду, или это может быть подлинной проблемой с блокировками пробуждения Android?