我正在后台运行一项读取 GPS/网络位置的服务,需要执行以下操作:
在应用重启时不中断地在后台运行,并尽可能保持其存活而不被杀死(这在 Merlin 的下面评论的帮助下解决了)
在收到的新位置上,调用网络服务并发送读取的位置
每 60 秒运行一次重复性任务,并将最后一个位置重新发送到网络服务。如果用户停留在同一位置,这将有所帮助。
我考虑了一些事情,但我不确定我是否理解正确。该服务与主应用程序在同一线程中运行,因此在与 UI 线程相同的线程中将位置发送到服务器可能会触发 UI 卡住,这并不好。此外,我不确定 GPS/网络监听器是否有自己的线程或使用与应用程序相同的线程。
为了使事情更清楚,这里是服务的缩短代码:
public class GPSLoggerService extends Service {
@Override
public void onCreate() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 50, locationListenerNetwork);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 50, locationListenerGps);
scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
updateLocation(lastLocation);
}, 60, 60, TimeUnit.SECONDS);
return START_STICKY;
}
LocationListener locationListenerGps = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
}
...
}
LocationListener locationListenerNetwork = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
}
...
}
private void updateLocation(Location readLocation) {
//web service call
String response = WebServiceCalls.updateLocation(readLocation);
//log data in a local Sqlite database
saveLocation(readLocation)
}
我主要关心的是如何处理 updateLocation 调用并将其置于与主应用程序线程不同的线程中。我认为 scheduleTaskExecutor 不是可行的方法。有时,即使在我调用 stopService() 之后服务仍然存在,即使我告诉 TaskExecutor 关闭。我找不到服务没有停止的其他解释。 回顾一下:每次听众收到新位置时我都需要发送位置并每 60 秒重新发送一次。我还需要能够通过取消 Activity 线程快速停止服务。
您建议我如何处理我的案子?
最佳答案
我会使用 IntentService 并只使用 AlarmManager 来触发 Intent 。
这样做的主要优点是无需担心线程代码,因为它在后台工作
更新
另一个有趣的方法可以在 https://stackoverflow.com/a/7709140/808940 中找到
关于Android 服务和线程中运行的重复性任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11234680/