我很困惑我的應用程序的設計。我需要不斷輪詢服務器以從中獲取新數據。我很困惑以固定的時間間隔運行Async Task還是Service running是後臺更好的選擇。該線程將僅在應用程序運行時運行服務v/s AsyncTask
回答
Android Service不在後臺線程中。
因此,您應該運行一個服務,每次您要輪詢時都會啓動一個ASyncTask。
請注意,與其他應用程序對象一樣,服務在其宿主進程的主線程中運行。這意味着,如果你的服務要做任何CPU密集型(如MP3播放)或阻塞(如網絡)操作,它應該產生自己的線程來完成這項工作。有關這方面的更多信息可以在「進程和線程」中找到。 IntentService類可作爲Service的標準實現提供,它具有自己的線程,用於調度要完成的工作。
Service
不應與AsyncTask
相比較。我想你在這裏最有可能的意思是IntentService
- 儘管有通用名稱,但這與Service
稍有不同。
至於定期抓取,我會堅持使用反覆報警(使用AlarmManager
)和(最可能)使用IntentService
來抓取。
這裏你AsyncTask fundamentals和一些tutorials 了這裏你IntentService fundamentals和tutorials
注意得到,那IntentService
作業設計排隊,而AsyncTasks
可以運行完全相同常。但請注意regression related to AsyncTask handling in newer APIs。解決方案只是更多的代碼行,這不是什麼大問題,但值得一提的是。
編輯
有許多關於生命週期的AsyncTask是債券到活動的生命週期中的誤解浮動。這是錯誤。 AsyncTask獨立於Activity。 Finishing Activity對任何AsyncTasks都沒有做任何事情,除非你用代碼從onDestroy()清理它們。然而,如果一個活動的進程在後臺被殺害,那麼AsyncTask也將被殺死,因爲整個進程中的一部分被殺死。
如果你想「連續輪詢」,一個asyncTask贏得'不要做。當您的應用被Android停止時,任務停止。正如Blundell已經指出的那樣,服務本身也不會這樣做。服務在主線程中運行,並且您不希望在主線程中進行輪詢。有兩種方法:創建一個Service,它自己創建一個線程來完成您想要的任務,或者讓它調度在AsyncTask或獨立線程中執行的輪詢。我儘量不在我的應用程序中進行輪詢,但如果必須,請在您的服務中創建一個特殊線程,以便進行輪詢,這對我來說似乎是最好的。
根據您的應用程序的功能和輪詢的內容,您可以爲單獨的線程指定較低的優先級,這樣就不會妨礙其他處理。
**這就是城市傳奇** AsyncTask **與**無關。Finishing Activity對任何AsyncTasks都沒有做任何事情,除非你用代碼從onDestroy()清理它們。然而,如果一個活動的**進程**在後臺被殺害,那麼AsyncTask也會被殺死,因爲整個進程的一部分被殺死。 –
那你有什麼意見? AsyncTask不會確保應用程序保持輪詢,因爲當Android需要空間時,它會銷燬應用程序並停止輪詢。在一項服務中,投票繼續進行。我說「活動停止」而不是「應用程序停止」這一事實,這是您給我的答案投下的理由嗎?可憐...... – Christine
你在散佈虛假信息。起初,這是我的觀點。其次,正如我的回答所述,AsyncTask不適用於定期任務。最後,如果你不能接受批評,也許你不應該首先參加對話。 –
線程運行,只有當應用程序正在運行
然後AsyncTask
將是最簡單的解決方案。使用後臺線程中的publishProgress()
定期將數據發送到應用程序線程。使用Thread.sleep()
在doInBackground()
中設置所需的時間間隔。此外,請確保您在onResume()
活動方法中啓動新任務,並在活動的onPause()
方法中結束此任務。
例子:
public class MyActivity extends Activity {
private AsyncTask<Void,String,Void> mAsyncTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
mAsyncTask = new MyTask();
mAsyncTask.execute();
}
@Override
protected void onPause() {
super.onPause();
if(mAsyncTask != null){
mAsyncTask.cancel(true);
}
}
private void onServerResponse(String response){
Toast.makeText(this, "Got response !", Toast.LENGTH_SHORT).show();
}
private final class MyTask extends AsyncTask<Void,String,Void>{
@Override
protected Void doInBackground(Void... voids) {
while (!isCancelled()){
String response = "";
//server query code here
publishProgress(response);
Log.i("TEST", "Response received");
//sleep for 5 sec, exit if interrupted ,likely due to cancel(true) called
try{
Thread.sleep(5000);
}catch (InterruptedException e){
return null;
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
if(values.length > 0){
onServerResponse(values[0]);
}
}
}
}
你已經有些答覆你的問題,但我認爲這一點,實在值得總結...
你需要什麼
當你想運行需要一些時間才能完成的代碼應始終在UI線程的單獨線程中運行。
可以實現在2種方式:
使用Thread
:
這是最簡單的一種,如果不從,新線程UI線程需要大量的溝通。如果你需要溝通,你可能不得不使用Handler
來做到這一點。
使用AsyncTask
:
在一個單獨的線程也可以運行,並已經實現了與UI線程一些溝通渠道。因此,如果您需要將此通信返回到用戶界面,則最好使用此方法。
你不需要什麼
Service
這主要是用來保留一些代碼,你退出主應用程序即使在運行,除非你生成一個新的,將在UI線程中運行線程使用上述選項。你說你的線程是在你退出應用程序時被終止的,所以這不是你所需要的。
IntentService
這可以通過可以就一塊由你定義的代碼,即使應用程序未運行時的外部事件(即BroadcastReceiver
)被激活。再次根據您的要求,這不是您正在尋找的。
問候。
而不是一個線程,您可以使用一個執行程序。如果您希望輪詢在Android將應用從堆棧中移除時繼續進行,那麼您確實需要一項服務。你不希望它繼續下去,那麼服務是你不需要的開銷。 – Christine
我不同意第3點關於服務。你說「你說你的線程是在你退出應用程序時被終止的,所以這不是你需要的。」,這是正確的。但是配置更改呢?屏幕方向改變和用戶攔截呼叫? - 否則寫得很好! –
- 1. Android Asynctask vs Runnable vs timertask vs服務
- 2. 服務vs可運行vs AsyncTask
- 3. Asynctask與服務
- 4. Android:AsyncTask vs服務
- 5. 使用AsyncTask服務
- 6. AsyncTask vs Activity.runOnUiThread()vs Handler.post()
- 7. AsyncTask類VS AsyncTask對象
- 8. 服務vs AsyncTask來處理配置更改和TCP連接
- 9. Asynctask vs IntentService用於與後端mysql服務器同步
- 10. Android:RunOnUiThread vs AsyncTask
- 11. AsyncTaskLoader vs AsyncTask
- 12. web服務VS WCF服務
- 13. 域服務vs WCF服務?
- 14. Android AsyncTask vs Thread + Handler vs rxjava
- 15. 要使用AsyncTask或服務?
- 16. Android綁定服務與AsyncTask
- 17. 從服務執行AsyncTask
- 18. 服務或線程或AsyncTask?
- 19. AsyncTask服務無法訪問
- 20. 如何使用AsyncTask服務?
- 21. 在服務中使用AsyncTask
- 22. 的Android的AsyncTask和服務
- 23. 服務或線程或AsyncTask
- 24. 服務VS螺紋
- 25. HttpContext.Items vs Scoped服務
- 26. 關注vs服務
- 27. TDD VS BDD:REST服務
- 28. RMI vs REST服務
- 29. 語境VS服務
- 30. web服務器vs部署服務器
IntentService不是更多的隊列類型體系結構嗎? – Ankuj
是的,但我認爲它不是定期抓取的問題,除非抓取可以重疊。我個人主要使用'AsyncTask',但這一切都取決於應用程序體系結構。 –
另外我還有一個疑問。像異步任務與UI線程鏈接。但是這個輪詢將獨立於UI開始,並且不需要給用戶任何通知,所以我想這可能排除其中一個缺點 – Ankuj