Android: поток C ++ не просыпается, если экран заблокирован или находится в фоновом режиме. Работает нормально, когда приложение используется

В нашем приложении для Android есть компонент пользовательского интерфейса и модуль ядра C ++ 11. Поток работает на основе std::chrono::system_clock::time_point, такие как ниже:

while(this->m_ConditionVariable.wait_until(lock, this->m_Object.to_time_point())
== std::cv_status::no_timeout)
{
// ... handle any notify() or arbitrary sleep breaks
}

Execute();  // <--- not being called consistently

Сейчас мы тестируем с 1 минуты time_point, Если приложение используется, то Execute() вызывается, как и ожидалось. Однако, если приложение перемещается в фоновый режим или экран заблокирован, Execute()поведение не соответствует.
Иногда он может работать должным образом каждую минуту в течение 15 минут, и после этого он будет вызываться через 2 минуты, 3 минуты или 10 минут вместо фиксированной 1 минуты. Используя отладки, мы проверили, что time_point поставляется правильно.

Предположим, что если мы запустим приложение в режиме отладки (с помощью Android Studio), то оно будет отлично работать даже в фоновом режиме и в режиме блокировки экрана.

Есть ли у Android приоритет потоков для приложения, работающего в фоновом режиме?


Обновление 1В основном фоновый поток собирает информацию о местоположении. Я наткнулся на вопрос ниже, который предполагает, что в Android, когда телефон заблокирован, выполнение потока останавливается. Я застрял в этой проблеме?
Приложение перестает работать, когда экран заходит в спящий режим

Обновление 2: С частичным Wake Lock, это работает отлично. Но не уверен, что это хорошее решение. Если это единственный способ, я был бы признателен за стратегию оптимального использования.

Обновление 3: Если я заменю wait() с меньшим sleep(), то он работает нормально даже без какой-либо Android Wake Lock. Однако нам еще предстоит провести регрессивное тестирование на нем.

3

Решение

Когда устройство находится в режиме ожидания, центральный процессор останавливается, и любой выполняемый поток приостанавливается (C ++ или Java). Если он по какой-либо причине просыпается, ваш поток C ++ снова начинает работать, поэтому возникает случайное поведение: другие приложения или службы могут время от времени пробуждать устройство.

Добавление частичной блокировки следа работает в вашем случае, но это предотвратит работу процессора в режиме ожидания, что приведет к разрядке батареи. Если вам все равно, вы можете использовать этот подход, если батарея работает, Вы можете использовать API аварийного сигнала Java для регулярного пробуждения устройства. Тогда API Java может вызывать код C ++ через JNI..

Документация Android для повторных сигналов тревоги: https://developer.android.com/training/scheduling/alarms.html

Для обновления 3, используя небольшой сон, а не wait()Я подозреваю, что Android не переходит в режим ожидания во время работы потока, может быть, он ожидает небольшой тайм-аут без активного потока, прежде чем переходит в режим ожидания. Этот подход будет иметь тот же эффект на разрядку батареи, что и блокировка.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]