我应该在我的Android应用中使用Service还是IntentService?

9

如果我错了,请纠正我:

1) Service 用于在后台执行长时间任务。服务在UI线程中运行,因此,如果有长时间的任务,则可能会冻结我们的UI。只要我们告诉它停止,服务将独立于应用程序继续运行。

2) 另一方面,IntentService 用于在单独的线程中执行短时间任务。它在完成任务后自动终止。

我需要做什么:

1) 每5秒检查位置

2) 如果位置有变化,则将其发送到服务器,并使用新的位置值更新UI

我感到困惑的是:

我应该使用 Service 还是 IntentService,因为我需要每隔5秒持续地执行它,而不希望我的UI线程变得不响应。

这个应用程序将用于跟踪车辆。

6个回答

3
我不建议使用 IntentService,因为它在完成任务后会自动结束,你需要在 5 秒后重新安排任务。要重新安排任务,你需要一个与应用程序上下文相关的复杂外部计时器机制,或者更糟糕的是使用 AlarmManager,这会让你的电池消耗得很快。
我建议使用一个带有定时器的 Service 来调度每 5 秒的 TimerTasks,在每个 TimerTask 上,无论如何都会在工作线程上执行,我将获取位置并进行 Http 请求。
只需不要忘记在 Service 的 onDestroy 方法中取消定时器,否则你将泄漏 Service 实例。
编辑:我刚注意到这一点,“更新 UI 的新位置值”...继续使用 Service,但要么在 doInBackground 中使用 AsyncTask 发送请求,然后在 onPostExecute 中发送广播消息,要么继续使用相同的 TimerTask 机制,但使用一个实例化了 UI Looper 的 Handler,并在该处理程序上进行 UI 更新请求。

1
每5秒运行一次请求位置服务会对电池寿命产生什么影响? - Greg Ennis
@GregEnnis:好问题,也许应该作为一个单独的SO问题提出。我认为这取决于每个制造商,因为我不希望每个设备在同一时间内都耗尽电池。但如果功能请求是这样的,我会建议只有在真正需要位置更新时才集中处理。例如,在相关Activity的可见期间(onResume-onPause)期间。一旦不需要位置更新,停止请求位置更新并关闭服务。回答您的问题了吗? - gunar

2

1) Service用于在后台执行长时间任务。Service在UI线程中运行,因此如果有长时间任务,则可能会冻结我们的UI。

是的,但当您使用Service执行某些长时间任务时,您需要在其中创建线程。 Service的一个非常重要的特性是,如果内存不足,则Android系统不太可能杀死您的应用程序。如果您使用setForeground,则它将更少地杀死您的应用程序。

只要我们告诉它停止,Service将继续独立于应用程序运行。

它将在您的应用程序进程中运行,因此您无法告诉它是否独立运行。您当然可以从应用程序中停止它,或者如果它完成了其工作,则服务可以自行停止。

2) 另一方面,IntentService用于在单独的线程中执行短任务。它在完成任务后会自动终止。

IntentService扩展了Service,并使实现Service变得更加容易,它在自己的工作线程上运行您的代码。如果没有更多排队的工作要做,它将终止。

如果我需要每5秒连续执行并且不希望我的UI线程变得不响应,我应该使用Service还是IntentService。

它非常取决于您的任务,如果您的工作是由UI触发的某个函数触发的,则使用IntentService。裸服务确实适用于非常长的任务,例如像mp3播放器或者如果您需要与服务器进行持续通信。

如果您的任务可以在应用程序后台运行,即由BroadcastReceiver触发,则应查看wakeful intentservice:

https://github.com/commonsguy/cwac-wakeful

它将使您的应用程序保持活动状态,直到intentservice处理您的作业为止,否则Android允许在广播onReceive返回后杀死您的应用程序。


1

0
关于位置
有一个位置距离更新 -> 即如果手机的位置变化超过X米,则发送更新,不要每5秒询问一次,如果您在移动车辆中,那么X米将很快过去,如果您正在步行,则永远不会移动超过3-5米的5秒钟 - 人们会抱怨您的应用程序耗尽他们的电池。
另外 - 只有当您的应用程序未运行时,服务才会继续运行,如果您启动它为粘性。否则,当您的应用程序从应用程序队列中销毁时,服务也将被销毁。
requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)
Register for location updates using a Criteria and pending intent.
void     requestLocationUpdates(long minTime, float minDistance, Criteria criteria, LocationListener listener, Looper looper)
Register for location updates using a Criteria, and a callback on the specified looper thread.
void     requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
Register for location updates using the named provider, and a pending intent.
void     requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener, Looper looper)
Register for location updates using the named provider, and a callback on the specified looper thread.
void     requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)
Register for location updates using the named provider, and a pending intent.

位置 API


0

如果您不想使用任何服务,那么可以使用位置API的功能。您需要注册您的位置管理器以提供最新的位置信息。如果您需要使用其中的一个服务,则

  IntentService 

是您的最佳选择。

locationManager.requestLocationUpdates(provider,
                        5000 ,
                        10, new myLocationListener());

这是您的位置监听器类。

public class myLocationListener implements LocationListener{
@Override
    public void onLocationChanged(Location location) {
        // Here you can get latest location and update to server
       //location object provides you to latest location.

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }
}

请在此答案对您有帮助时标记接受。

我知道它会每5秒更新一次位置,但问题是如果我的应用程序终止,那么它将无法向服务器发送更新。我想要一个可靠的机制,即使应用程序终止也能继续向服务器发送位置数据。该应用程序将用于跟踪车辆。 - Rakesh
因此,在您的应用程序关闭时,即在启动器活动的onDestroy()方法中注册一个间隔时间为5分钟的闹钟。然后,您可以在闹钟广播中获取最新位置并检查其是否已更新。如果已更新,则将其更新到服务器。 - Solution
那么locationmanager是否在服务中注册请求更新?因为如果它是在一个活动(UI绑定组件)中完成的,那么它的整个意义就失去了。 - gaara87

0

IntentService 继承自 Service,并为您创建一个线程并管理其生命周期。

如果您正在检查用户位置,特别是与较新的 Android 位置策略 结合使用,应该使用 IntentService。您可以使用地理围栏让操作系统为您完成工作,并节省电池电量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接