Android服务和线程中运行的重复任务

Ali*_*lin 5 service android background scheduled-tasks

我在后台运行一个读取GPS /网络位置的服务,需要执行以下操作:

  • 在没有中断应用程序重启的情况下在后台运行并尽可能保持活着而不会被杀死(这可以通过Merlin的评论帮助解决)

  • 在收到的新位置,调用Web服务并发送读取位置

  • 每60秒运行一次重复任务,并将最后一个位置重新发送到Web服务.这将有助于用户保持在相同位置.

我考虑了一些事情,我不确定我是否理解正确.该服务在与主应用程序相同的线程中运行,因此在与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) 
}
Run Code Online (Sandbox Code Playgroud)

我主要关心的是如何处理updateLocation调用并将其放在与主应用程序线程不同的线程中.scheduleTaskExecutor我相信它不是要走的路.有时候,即使我告诉TaskExecutor关闭了,即使在我调用stopService()之后服务仍然存活.我找不到服务没有停止的另一种解释.所以回顾一下:每次听众收到一个新位置并每隔60秒重新发送一次,我需要发送该位置.我还需要能够通过活动线程取消来快速停止服务.

你会如何推荐我处理我的案子?

Dha*_*dra 1

为了防止您的服务被破坏,您可以将您的服务作为前台服务启动。

从 onLocationChanged() 方法获取位置后,您可以使用asynctask将位置发送到 Web 服务,这样它就不会阻塞您的 UI。

编辑

  1. 您可以在requestLocationUpdates方法中设置最短行驶时间和最短行驶距离。所以我认为您不应该使用调度程序任务将位置发送到服务器。根据有关最短时间和最短距离的参数,位置管理器将检查位置。如果位置发生更改,它将使用新位置调用 onLocationChanged() 方法。现在,关于用户保持在同一位置的解决方案。您可以更改服务器端的一些逻辑,例如,如果两个连续位置 location1 和 location2 之间存在 1 小时差异,则意味着用户在 location1 停留了 1 小时。

  2. 您可以使用单个 LocationListener 类来侦听 GPS 和网络位置。

  3. 当您在 onLocationChanged() 方法中获取位置时,您可以使用 asynctask 发送该位置。
  4. 获取位置后,您可以将该位置保存在首选项或数据库中,以检查 GPS 和网络提供商向您发送相同位置的天气情况,因此如果您愿意跟踪,则可以保存您的 webAPI 调用,这样您就可以节省部分电池。