服务与AsyncTask

时间:2012-10-28 15:16:35

标签: android android-asynctask android-service

我对我的应用程序的设计感到困惑。我需要不断轮询服务器以从中获取新数据。我很困惑是以固定间隔运行Async Task还是运行Service是更好的选择。该线程仅在应用程序运行时运行

5 个答案:

答案 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 fundamentalstutorials 在这里,你得到了IntentService fundamentalstutorials

请注意,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]);
            }
        }
    }
}