2017-04-21 29 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/