В нашем приложении для 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. Однако нам еще предстоит провести регрессивное тестирование на нем.
Когда устройство находится в режиме ожидания, центральный процессор останавливается, и любой выполняемый поток приостанавливается (C ++ или Java). Если он по какой-либо причине просыпается, ваш поток C ++ снова начинает работать, поэтому возникает случайное поведение: другие приложения или службы могут время от времени пробуждать устройство.
Добавление частичной блокировки следа работает в вашем случае, но это предотвратит работу процессора в режиме ожидания, что приведет к разрядке батареи. Если вам все равно, вы можете использовать этот подход, если батарея работает, Вы можете использовать API аварийного сигнала Java для регулярного пробуждения устройства. Тогда API Java может вызывать код C ++ через JNI..
Документация Android для повторных сигналов тревоги: https://developer.android.com/training/scheduling/alarms.html
Для обновления 3, используя небольшой сон, а не wait()
Я подозреваю, что Android не переходит в режим ожидания во время работы потока, может быть, он ожидает небольшой тайм-аут без активного потока, прежде чем переходит в режим ожидания. Этот подход будет иметь тот же эффект на разрядку батареи, что и блокировка.
Других решений пока нет …