我对我的应用程序的设计感到困惑。我需要不断轮询服务器以从中获取新数据。我很困惑是以固定间隔运行Async Task还是运行Service是更好的选择。该线程仅在应用程序运行时运行
答案 0 :(得分:5)
你已经对你的问题有了一些答案,但我认为值得总结......
您需要什么
如果要运行需要一些时间才能完成的代码,应始终在UI线程的单独线程中运行它。
您可以通过两种方式实现这一目标:
使用Thread
:
这是最简单的一个,如果您不需要从新线程到UI线程的大量通信。如果您需要通信,则可能需要使用Handler
来执行此操作。
使用AsyncTask
:
还在单独的线程中运行,并且已经使用UI线程实现了一些通信通道。因此,如果您需要将此通信返回到UI,则最好使用此方法。
您不需要的内容
Service
这主要用于在退出主应用程序后保持一些代码运行,并且它将在UI线程中运行,除非您使用上述选项生成新线程。你说当你退出应用程序时你的线程会被终止,所以这不是你需要的。
IntentService
这可以通过外部事件(即BroadcastReceiver
)激活,该事件可以启动您定义的代码,即使您的应用程序未运行。再一次,根据您的要求,这不是您想要的。
问候。
答案 1 :(得分:2)
Android Service不在后台主题中。
因此,您应该运行一个Service,每次要轮询时都会启动ASyncTask。
请注意,服务与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果您的服务要进行任何CPU密集型(例如MP3播放)或阻止(例如网络)操作,它应该生成自己的线程来执行该工作。有关此内容的更多信息,请参见进程和线程。 IntentService类可用作Service的标准实现,它具有自己的线程,用于调度其工作。
答案 2 :(得分:1)
Service
不应与AsyncTask
进行比较。我猜你最有可能在这里IntentService
- 这与Service
略有不同,尽管有一个共同的名字。
至于定期提取,我会坚持反复发出警报(使用AlarmManager
)并且(很可能)使用IntentService
进行提取。
您来自AsyncTask fundamentals和tutorials 在这里,你得到了IntentService fundamentals和tutorials
请注意,IntentService
个作业按设计排队,而AsyncTasks
可以完全填充。但请注意regression related to AsyncTask handling in newer APIs。没有什么大不了的,因为解决方法只是更多的代码行,但值得了解。
修改强>
有很多关于AsyncTask生命周期与Activity的生命周期保持联系的误解。这是错误。 AsyncTask独立于Activity。 Finishing Activity不会对任何AsyncTasks执行任何操作,除非您通过代码从onDestroy()清除它们。然而,如果一个活动的进程在后台被杀死,那么AsyncTask也将被杀死,作为整个进程被杀死的一部分
答案 3 :(得分:1)
如果你想“连续轮询”,asyncTask就不会这样做。当您的应用被Android停止时,任务就会停止。正如Blundell已经指出的那样,服务本身也不会这样做。服务在主线程中运行,您不希望在主线程中进行轮询。有两种方法:创建一个服务,它生成自己的线程来完成你想要它做的事情,或者你让它安排在AsyncTask或单独的线程中执行的轮询。我尽量不在我的应用程序中进行轮询,但如果必须,在您的服务中创建一个特殊的线程来进行轮询似乎对我来说最好。
根据您的应用程序执行的操作以及轮询的内容,您可以为单独的线程赋予较低的优先级,因此不会妨碍其他处理。
答案 4 :(得分:0)
该线程仅在应用程序运行时运行
然后AsyncTask
将是最简单的解决方案。使用后台线程中的publishProgress()
定期向app线程发送数据。使用Thread.sleep()
中的doInBackground()
设置所需的时间间隔。另外,请确保在onResume()
Activity方法中启动 new 任务,并在onPause()
Activity方法中结束此任务。
示例:
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]);
}
}
}
}