Связанный с WakeLock Mandelbug: всегда ли WakeLock.acquire () успешен? - PullRequest
1 голос
/ 25 августа 2011

Проблема

Я давно занимаюсь разработкой под 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?

1 Ответ

0 голосов
/ 21 января 2012

Может показаться, что это действительно проблема параллелизма.Я упустил из виду тот факт, что соответствующий метод может вызываться из несинхронизированного местоположения в отдельном потоке - очевидная проблема в многопоточной среде!

...