一次性修复用户位置(通过 GPS)的正确控制流程是什么?
我正在寻找“正确”的方法来修复用户的位置作为一次性任务。目前,我的执行流程大致是:
- 用户按下按钮。
- 处理程序(包含在主 Activity 代码中)向系统注册 GPS 位置侦听器,设置为尽快更新,启动 ASyncTask,然后完成。
- 执行前,ASyncTask 生成一个 ProgressDialog,有效阻止任何其他 UI 使用。
- 对于其后台任务,ASyncTask 会等待超时或 GPS 位置修复。
- 执行后,如果找到位置,ASyncTask 会向用户显示一些相关数据;如果没有找到,则在 Toast 中显示错误。当然,它也会注销监听器。
现在,虽然这种方法有效,但也存在许多缺点。首先,很明显,在发出请求时,与应用程序的所有其他 UI 交互都会被阻止。目前这还不算太糟糕,因为应用程序的主要功能是执行此任务,并且在工作时没有太多其他事情可做 - 它还可以阻止用户向按钮发送垃圾邮件。此外,我不确定 ASyncTask 的执行后阶段是否真的是放置我的位置发现逻辑的地方(它进行互联网调用,这本身在 ASyncTask 中可能会更好?)。但是,我不确定如何传回已找到位置并且主线程应该执行某些操作的事实。
我希望有人能告诉我“正确”的方法来做到这一点 - 即正在使用像这样正确的 ASyncTask,是否涉及服务,以及我应该如何处理发现位置后的互联网呼叫),甚至可能给出一些明智的话,说明通常如何处理必须进行某种“阻塞”调用的应用程序的控制流。
如果需要,我可以提供代码,可能需要一些时间才能将其缩减为最小解决方案。
I'm looking to find the "correct" way to get a fix on the user's location as a one-time task. At the moment, my execution flow is roughly:
- The user presses a button.
- The handler (contained in the main Activity code) registers a GPS location listener with the system, set to update as fast as possible, launches an ASyncTask, and finishes.
- Pre-execution, the ASyncTask generates a ProgressDialog, effectively blocking any other UI usage.
- For it's background task the ASyncTask waits for either a timeout or for a location fix for the GPS.
- Post-execution, the ASyncTask either displays some relevant data to the user if a location was found, or displays an error in a toast if it was not. It also de-registers the listener of course.
Now, while this works, there are numerous downsides. Firstly, and quite obviously, all other UI interaction with the app is blocked while a request is being made. This isn't too bad currently, as the app's main function is to perform this task, and there isn't much else to do while it's working - it also stops the user from spamming the button. Additionally, I'm not sure if the post-execution phase of the ASyncTask is really the place to put my location-found logic (it makes an internet call, which is something that itself might be better off inside an ASyncTask?). However, I'm not sure how else to pass back the fact that a location has been found and that the main thread should do something.
I was hoping that someone could inform me as to the "right" way to do this - i.e. is using an ASyncTask like this correct, should there be a Service involved, and how should I deal with the internet-call post-location-found), and perhaps even give some wise words on how in general to deal with the control flow of an app which has to make somewhat "blocking" calls.
I can provide code if needed, might take a bit to get it cut down to a minimum solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常应避免阻塞调用和阻塞 UI。请参阅 Reto Meier 对此主题的看法。
因此,我将完全转储
AsyncTask
。禁用用户用来启动修复请求的Button
。使用postDelayed()
Runnable
作为超时机制。并且,允许用户执行某些操作(阅读帮助等)。使用标题栏中的进度指示器来指示您正在努力获取位置,当您获得修复或发生超时时,请关闭指示器。它当然不应该在主应用程序线程上完成。当位置修复出现时,启动
AsyncTask
来获取数据。Blocking calls and blocking UIs are generally to be avoided. See Reto Meier's take on the subject.
Hence, I'd dump the
AsyncTask
entirely. Disable theButton
that the user uses to kick off the fix request. Use apostDelayed()
Runnable
for your timeout mechanism. And, allow the user to do something (read help, etc.). Use the progress indicator in the title bar to indicate that you're working on getting the location, dismissing the indicator when you get a fix or when your timeout occurs.It certainly should not be done on the main application thread. When the location fix comes in, kick off the
AsyncTask
to fetch the data.