如何在Android中可靠地切换服务?

时间:2015-04-20 18:41:59

标签: android android-service

编辑:我特别担心在服务被杀的情况下更新我的切换。

我有一项活动,我希望向用户显示切换以启动或停止服务。活动应显示服务当前是否正在运行,因此活动需要知道服务是否正在运行。

此问题已在此处讨论:How to check if a service is running on Android?

有两个一般策略: 1)使用活动管理器获取正在运行的服务列表:ActivityManager.getRecentTasks()。缺点:getRecentTasks已被弃用且速度很慢。

2)使用服务类中的静态字段来切换状态。缺点:当服务被杀死时,不会调用服务的onDestroy()方法。因此,静态变量无法在这种情况下更新,并且活动可能会认为服务正在运行,而不是。

有没有办法解决这个更可靠的问题?我可以每隔N秒将静态变量重新设置为时间戳,如果活动看到静态变量太旧,我就知道该服务已被杀死。感觉很蠢,并且会有竞争条件。

2 个答案:

答案 0 :(得分:0)

我不知道它是否适用于您的情况,但我有一项服务,我在其上创建了一个静态启动方法MyService.startIfNeeded(context)。此方法根据某些内部数据库状态确定服务是否应该运行。如果它应该正在运行,则使用已传递的上下文启动MyService,否则它会调用stopService来终止它(这将调用onDestroy(),以便服务能够清除&#39} #39)。

调用Next onStartCommand(),此处读取非静态字段变量isRunning以确定是否应调用服务代码(在这种情况下读取WiFi信号)。

我想可以使用此方案的变体来获得您所寻求的功能。对我来说,关键是要使静态MyService.startIfNeeded(context)方法具有幂等性,因为如果它应该运行它会保持运行(并且不会重新启动),如果它不应该运行它会被破坏或者根本没有任何反应。

也许这在你的情况下毫无意义,只是想抛弃一些想法。

答案 1 :(得分:0)

也许下面的方法在某种程度上适合你:

  1. 广播驱动的消息传递通知活动有关服务的生命周期
  2. 最近我来自Google样本(https://github.com/googlesamples/android-JobScheduler/tree/master/Application/src/main/java/com/example/android/common/logger)的JobScheduler示例。
  3. 这里的方法是将Activity的messenger传递给Service,以便Service可以将自己在Message.obj中传递的消息发送到Activity,从而将Activity实例设置为成员。 此时,您可以直接在Activity上调用您的逻辑绑定方法来控制您的服务生命周期。

    简而言之: 连接到服务: https://github.com/googlesamples/android-JobScheduler/blob/master/Application/src/main/java/com/example/android/jobscheduler/MainActivity.java(第70-72行)

    从服务发送握手消息: https://github.com/googlesamples/android-JobScheduler/blob/master/Application/src/main/java/com/example/android/jobscheduler/service/TestJobService.java(第66行)

    将活动设为成员: MainActivity,第106 - 107行

    然而,当服务被杀时,他们都没有解决问题。