2017-04-21 26 views
1

我实现了一个凌空请求间隔火周期性的请求:凌空TimeoutError当应用睡着

final Handler handler = new Handler(); 

    final int interval = 3000; 

    handler.postDelayed(new Runnable() { 
     public void run() { 

      // Volley request here... 
      Volleyclient client = Volleyclient.getInstance(); 
      client.doSomeVolleyRequest(MainActivity.this, someListener, someDataToSend); 

      handler.postDelayed(this, interval); 
     } 
    }, interval); 

它的工作原理,只要细如应用程序是在前台。如果我推家里的按钮和应用程序睡着了,我有一个Volley TimeoutError,我不明白为什么。如果我切换到“待机”模式(屏幕关闭),则具有相同的行为。只要我将我的应用程序切换回前景,它就会继续排列请求。

我怀疑它不是真的超时,但在睡着的时候出现了互联网连接权限问题。我使用以下权限:

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.CALL_PHONE" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

是否有人能够解释该行为的原因? 如果你能告诉我一个解决方法,让我的应用程序在应用程序运行时继续发送请求,那就太好了。

回答

2

我认为问题在于你的线程。在UI线程中进入队列中的postDelayed操作。当手机进入睡眠状态时,没有用于工作的UI线程。我认为改变线程将解决这个问题。让我知道如果不行。

编辑:你说你的代码在你的活动。但是,当手机锁定(或黑屏)所有活动进入暂停状态。如果想继续工作,而电话睡觉,你必须使用服务。服务没有像活动一样的生命周期。他们会连接到电话并继续工作(即使您的应用程序已经死亡),直到您停止或用户中断为止。

有这很好地解释了一个例子:How to execute background task when Android app is closed/set to background?

+0

好吧,这是有道理的。该代码当前直接放置在我的MainActivity的onCreate-Method中。你能指点我一个简单的解决方案,通过发布一个链接或一些示例代码把它放到另一个线程中吗? – steven

+0

我现在将所有内容都迁移到了服务中。在真实设备上的行为几乎相同。如果我通过USB连接(调试),它将继续发送,如果应用程序不在前台。如果我断开USB,它不会在前景中给我一个Volley TimeoutError。在所有情况下,在睡眠模式下发送失败(显示关闭)。一切工作正常,如果我把应用程序回到前台。很奇怪,很讨厌。 – steven

+0

似乎是服务本身在后台正常工作的情况。在所有情况下,在后台运行时会周期性显示错误Toast ist,因此线程似乎运行。只是凌空通信失败。 – steven

0

后的研究很长一段时间,我现在能够回答我的问题。 我讨厌它,但没人能弄明白。

描述行为的简单原因是:打盹模式!

这不是一个线程问题,它仅仅是一个由于打瞌睡模式导致的禁用网络访问。休眠模式的一个特点是:网络访问被暂停。

https://developer.android.com/training/monitoring-device-state/doze-standby.html

https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/