我有需要做以下服务: - 不断地监听GPS位置,以50米作为参数(正常工作),并发送到服务器 - 每60秒,如果没有读取GPS位置,开始监听网络位置并将其发送到服务器
这听起来很奇怪,但这是项目要求。因此,用户一直在使用GPS进行跟踪。当他停下来,或GPS没有锁定,或者在建筑物内时,每隔60秒开始一次快速的网络位置读取,并将此位置发送到服务器。由于该服务使用与主应用程序相同的线程,因此每个服务器更新都在其自己的线程中完成。还有一件重要的事情:每个位置读取应该一个接一个地发送,例如,如果用户正在驾驶,并且多次读取完成,则每个位置应该在前一个发送之后发送到服务器。这就是为什么我决定使用ScheduledExecutorService,因为我可以提交线程,他们将一个接一个地执行。
下面是代码:
private ScheduledExecutorService scheduleTaskExecutor;
Handler locationHandler = new Handler();
private Location lastNetworkLocation;
@Override
public void onStartCommand() {
scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();
//prepare to execute Network reading every 60 seconds
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
initNetworkReadings();
//usually a network location read is done almost instantly
//however after 5 seconds I check if a location has been read by the Network listener inside the locationRunnable
locationHandler.postDelayed(locationRunnable, 5000);
}
}
}, 60, 60, TimeUnit.SECONDS);
locationRunnable = new Runnable() {
@Override
public void run() {
if (lastNetworkLocation !=null){
//send location to the server if valid
}
lastNetworkLocation = null;
}
}
}
private void initNetworkReadings() {
locationManager.removeUpdates(locationListenerNetwork);
try {
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
if (isGpsEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
}
}
LocationListener locationListenerNetwork = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
lastNetworkLocation = location;
// stop listening for Network locations
locationManager.removeUpdates(locationListenerNetwork);
}
...
}
每次我读了GPS位置我将它添加到线程的队列:
scheduleTaskExecutor.submit(new Runnable() {
@Override
public void run() {
updateLocationOnServer(readLocation);
}
});
我的问题是,网络位置听众从来没有得到onLocationChanged()
调用,当我使用它在上面的代码中,在Runnable中。但如果我加上服务启动,initNetworkReadings()
,我得到onLocationChanged()
立即开除。所以我认为这与在scheduleAtFixedRate中使用有关。 您认为这可能是什么问题?我想到工作流程的方式有什么不好?