2016-11-29 19 views
3

在我们的Android应用程序中,我们有UI组件和核心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() -s行为也不一致。
有时候,它可能每分钟工作15分钟,然后在2分钟或3分钟或10分钟后调用,而不是固定1分钟。使用调试,我们检查了,提供的time_point是正确的。

假设如果我们在调试模式下运行应用程序(使用Android Studio),那么即使在后台和屏幕锁定模式下它也能正常工作。

对于在后台运行的应用程序,Android是否有任何线程优先级?


更新1:基本上后台线程收集位置信息。我遇到了下面的问题,这表明在Android中,当手机被锁定时,线程执行被暂停。我坚持这个问题吗?
App seems to stop working when the screen goes to sleep

更新2:随着部分Wake lock,它工作正常。但不知道这是否是一个好的解决方案。如果这是唯一的方法,那么我会很感激如何优化使用它的策略。

更新3:如果我将wait()更换为更小的sleep(),那么即使没有任何Android唤醒锁,它也可以正常工作。但是我们还没有对它进行回归测试。

回答

4

当设备空闲时,CPU停止并且任何正在运行的线程暂停(C++或Java)。如果它由于任何原因而被唤醒,那么C++线程将再次开始工作,因此是随机行为:其他应用程序或服务可能会偶尔唤醒设备。

添加一个部分唤醒锁在你的情况下工作,但会阻止CPU空闲,这会导致一些电池消耗。如果你不在意,你可以使用这种方法,如果电池存在问题,你可以使用Java警报API定期唤醒设备。然后,Java API可以通过JNI调用C++代码。

重复报警Android文档:https://developer.android.com/training/scheduling/alarms.html

对于更新3,使用一个小的睡眠,而不是wait(),我怀疑Android的线程运行时不会在空闲模式下,也许它等待小超时没有任何线程在闲置之前处于活动状态。这种方法对电池消耗的影响与唤醒锁相同。

+1

你有什么想法,为什么'sleep()'的东西有效。即如果我把“睡眠(1)”,那么它会在1秒后出来。实际上,我们尝试了Java Alarm API。在高层次上,这个API似乎影响到主GUI线程。 C++线程保持不受影响,仍然无法唤醒。如果你可以在这个API和它与C++线程的任何关系上提供更多的信息,这将是有益的。 – iammilind

+0

我通过编辑我的评论回复。这只是一个猜测。 对于Java报警API,我想你需要从服务线程调用它,以便它不与GUI链接。 –

相关问题