2016-11-29 2 views
3

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

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 какой-либо приоритет для приложений, работающих в фоновом режиме?


Update 1: В основном фоновый поток сбора информации о местоположении. Я столкнулся с вопросом ниже, что говорит о том, что в Android, когда телефон заблокирован, выполнение потока приостанавливается. Я придерживаюсь этой проблемы?
App seems to stop working when the screen goes to sleep

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

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

ответ

4

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

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

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

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

+1

Есть ли у вас какие-либо идеи, почему 'sleep()' работает. т. е. если я положу 'sleep (1)', то он выйдет из него через 1 секунду. На самом деле мы попробовали Java Alarm API. На высоком уровне кажется, что этот API влияет на основной поток графического интерфейса. C++ поток остался незатронутым и все еще не мог проснуться. Это будет полезно, если вы можете добавить дополнительную информацию об этом API и любых отношениях, связанных с потоками C++. – iammilind

+0

Я ответил, отредактировав свой комментарий.Впрочем, это просто предположение. Для API Java Alarm API, я думаю, вам нужно будет вызвать его из потока услуг, чтобы он не связывался с графическим интерфейсом. –

Смежные вопросы