gpt4 book ai didi

android - 在 Android 中长期运行的服务中读取、存储和发送读取的 GPS 位置

转载 作者:行者123 更新时间:2023-11-29 00:36:59 25 4
gpt4 key购买 nike

场景

第 1 步:启动位置管理器每 50 米读取一次 GPS 位置:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 50, locationListenerGps);

第 2 步:每次读取位置时:

@Override
public void onLocationChanged(Location location) {
new Thread(new Runnable() {
@Override
public void run() {
sendLocation(location);
}
}).start();
}

第 3 步:在 sendLocation 上我做了几件事:

  • 查询本地sqlite数据库是否有发送失败的记录
  • 如果有的话,将它们与当前位置一起发送到网络服务
  • 如果没有,只发送当前位置
  • 如果发送失败(主要是因为数据连接),在数据库中插入位置以供将来读取
  • 如果发送成功,从数据库中删除所有行

问题

所有这些都是在后台服务中完成的。对于每个 sendLocation 调用,我都会创建一个新线程。虽然连接正常,但一切正常。但是,当发送失败并且用户正在开车时,位置读取经常发生,并且很有可能有 2-3 个线程都试图发送相同的未发送位置。如果 Thread1 收到列表并尝试发送它,Thread2 和 Thread3 应该无法读取它并尝试发送它,因为 Thread1 可能会成功发送它。我怎样才能防止这种情况发生?如何确保 Thread2 不读取列表?

根据我现在的想法,我可以在表“processing”中添加一个新字段,并且对于检索到的所有要发送的行,将该字段更新为 true。在这种情况下,Thread2 将只获得 processing=false 行。这是一个解决方案吗?还有其他建议吗?我仍然认为 Thread2 获取数据有轻微的变化,而 Thread1 正在更新处理......谢谢。

后期编辑:额外的想法和想法我已经尝试过这种方法

private ExecutorService threadPool;

@Override
public void onCreate() {
scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();
threadPool = Executors.newSingleThreadExecutor();

//also need to send location every 60 seconds if no other location was read
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
sendLocation(lastLocation);
}
}, 60, 60, TimeUnit.SECONDS);
}


@Override
public void onLocationChanged(Location location) {
threadPool.execute(new Runnable() {
@Override
public void run() {
sendLocation(location);
}
});
}

@Override
public void onDestroy() {
threadPool.shutdownNow();
}

根据我的阅读,这个 threadPool 应该强制线程一个接一个地执行,对吧? (即使我确实觉得我误解了它的目的)如果是这样,如果我一个小时没有连接会怎样?对于每个位置读取,都会添加一个新线程......但是这个线程持续多长时间?我担心如果用户开得非常快会发生什么情况,我可以每 1-2 秒读取一次位置信息,这种机制是否会将我的 Web 访问保持在一个队列中,一个线程接一个线程?

换个思路,如果服务的 onCreate 方法创建一个新线程会怎么样。像这样的东西:

 @Override
public void onCreate() {
new Thread(new Runnable() {
@Override
public void run() {
startLocationListener();
}
}).start();
}

在 startLocationListener() 中,我开始读取 GPS 位置。 onLocationChanged 是否会在此线程上执行并且不会干扰我的 UI 线程?

使用在自己的线程中运行的服务是否更明智?这样我就不必担心线程问题了?

使用当前的方法,应用程序完成了工作,但随机发生了一些错误并且无法找出原因:我的一个 Activity 绑定(bind)到服务以接收更新,当应用程序获取时我小心地解除绑定(bind)onPause...但有时该服务会继续运行,因为我可以看到它显示的通知图标。我将对此进行更多调查,但我需要确定一种强大/可靠的方式来处理位置读取和发送。

稍后再编辑

这种方法怎么样:

private ExecutorService scheduleTaskExecutor;

@Override
public void onCreate() {
scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();

//also need to send location every 60 seconds if no other location was read
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
sendLocation(lastLocation);
}
}, 60, 60, TimeUnit.SECONDS);
}


@Override
public void onLocationChanged(Location location) {
scheduleTaskExecutor.submit(new Runnable() {
@Override
public void run() {
sendLocation(location);
}
});
}

@Override
public void onDestroy() {
scheduleTaskExecutor.shutdownNow();
}

最佳答案

让我直截了本地说:您想从后台线程一个接一个地发送位置信息。实现此目的的一个简单方案是(类似于您编辑的代码,但我看不出 ScheduledExecutor 的原因):

private ExecutorService exec;

@Override
public void onCreate() {
exec = Executors.newSingleThreadExecutor();
}


@Override
public void onLocationChanged(Location location) {
exec.submit(new Runnable() {
@Override
public void run() {
sendLocation(location);
}
});
}

@Override
public void onDestroy() {
exec.shutdownNow();
}

这在幕后所做的基本上是创建一个后台线程和一个任务队列。每次读取位置时,都会将新任务放入队列中。线程不断轮询队列,按顺序执行任务。

关于android - 在 Android 中长期运行的服务中读取、存储和发送读取的 GPS 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12044952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com