2012-05-18 125 views
7

在开发人员网站上阅读了大多数关于Android服务的可用文档,以及在这里的计算器中,我仍然对在单独任务中运行服务的几个方面感到困惑。希望有人能把我放在正确的轨道上。如何在Android服务中启动长时间运行的后台任务

比方说,我们有繁琐的业务框架,如

public class HliService extends Service { 

    @Override 
    public void onCreate() { 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // If we get killed, after returning from here, restart 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // We don't provide binding, so return null 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
    } 
} 

,并在清单中,我有

<service android:name=".HliService" android:process=":HLI_Comms"/> 

,这样服务在自己的线程中运行。

该服务的目的是提供一个后台任务,将 与使用TCP套接字的设备进行通信并执行其他操作。在忽略电池问题等风险,基本上我希望它永远运行。

喜欢的东西

// Method that communicates using a TCP socket, and needs to send 
// information back to the activity and receive messages from activity 
// not shown here. 
private void dummytask() { 

    boolean keepGoing = true; 
    while (keepGoing) { 
     // do useful stuff in here 
     // sets keepGoing false at some point 
    } 
    stopSelf(); 
} 

什么是发起这种方法/任务的最佳方法是什么?

我看过使用消息处理程序和活套的开发人员站点中的代码,我只能部分理解,但它看起来非常复杂,可能比我需要的更多?

我不相信我可以从onCreate()onStartCommand()调用此方法,因为从系统调用时都不会完成?我应该用计时器还是闹钟启动它?

我需要添加一个消息处理程序来与gui活动进行通信,但由于我在另一个线程中启动服务(凭借清单“process”指令),是否需要使用AIDL ?

我也看过使用AysnchTask而不是扩展Service,但它似乎更适合运行任务,然后终止。

+0

'while(keepGoing)' - 如果这是另一个线程,而不是将keep_inging设置为false的线程'keepGoing'必须是'volatile' - 在Java内存模型上读取 –

+0

请参阅此答案可能帮助您。 [此处输入链接的描述] [1] [1]:http://stackoverflow.com/a/13783477/2165080 –

回答

2

使服务运行在它自己的线程中。

这使服务在其自己的进程。这通常是需要避免的,因为它消耗额外的RAM和CPU(用于IPC)。您可以创建一个线程,只需创建Thread或任意数量的其他方法,其中大部分已经在Java中使用了十年左右。

在忽略电池问题等风险,基本上我希望它永远运行。

服务永远不可能运行。用户或操作系统最终会摆脱您的服务。

启动此方法/任务的最佳方法是什么?

从后台线程调用dummytask()

我需要使用AIDL吗?

。您的服务可以播放一个Intent,或调用由该活动提供的PendingIntent,也可以通过活动等的最佳提供的Messenger发送Message将是从Android支持使用LocalBroadcastManager包,但这不会跨越流程边界,迫使您进入更昂贵的通信选项。

+0

确定 - 感谢@CommonsWare。我也研究过这种方法,但我也不确定实施它的某些方面 - 我会做更多的研究,并可能会发布后续问题。我会就不使用“流程”提出建议。顺便说一句,我知道这项服务实际上不会永远运行 - 这只是一种简化。再次感谢。 – SteveJP

+0

@CommonsWare感谢上面的解释......真的很好 – Biplab

0

我认为你可以使用IntentService,你可以通过设置一个(常规)闹钟(AlarmManager.setRepeating)和PendingIntent来运行它。您可以通过从IntentService广播Intent并通过BroadcastReceiver在您的用户界面中接收它来通知UI。

+0

谢谢@omoling - 这不是更适合于只运行一个小任务,然后终止,而是启动一个长期运行的过程? – SteveJP

相关问题