So, after a rather long absence from Android, I decided to dive back in and start tweaking an app I started a while back. This particular app uses the GPS to store a location in a database. The problem was, the app would sometimes try and store the location before the GPS was even ready, resulting in coordinates of 0, 0. At the same time, I also wanted the GPS reading to be as accurate as possible before it was stored in the database. Accuracy of +/- 80 feet is not so useful in the long run.
After some thought on how best to accomplish this without pissing off the user (nobody likes an application that seems to hang, even if there is something ticking in the background), I settled on displaying a ProgressDialog to let the user that something is indeed happening, and they can continue once its done.
So, after reading up on this particular dialog, I found that there are two flavors: indeterminate and non-indeterminate. The non-indeterminate variety shows a progress bar, and can be handy when you have something measurable to load. The indeterminate variety simply shows a spinner with a message, and is therefore good for non-measurable load times. For my situation, the indeterminate variety is fine.
So, choice in hand, I set out to write some code. My first draft looked like this:
ProgressDialog spinnerDialog = ProgressDialog.show( Placeholder.this, "", "Waiting for accurate (> 10 meters) GPS coordinates...Please wait. ", true); refineGPSAccuracy(); spinnerDialog.dismiss();
The ProgressDialog takes four arguments: a context, a title (which Ive left blank), the message to be displayed, and whether or not the spinner is indeterminate. After creating one of these, I call my method, and once thats done, dismiss the spinner. Pretty simple, right? Well, yes, but the problem is that the code as we have it won’t work. If you tried to run this, your method would fire off, the app would hang until the method returned, and your spinner would be nowhere to be seen.
Why is this? Well, the quick answer is, calling the method is blocking the UI thread, meaning that your nice dialog will not show up until the method has returned, at which point we dismiss the dialog. So, how do we get around this? Create a thread for the method to run in. This way, it won’t block the main UI thread, and our spinner will be displayed in all its glory.
Version 2 of my code looked like this:
ProgressDialog spinnerDialog = ProgressDialog.show(
Placeholder.this, "",
"Waiting for accurate (> 10 meters) GPS coordinates...Please wait. ", true);
new Thread(new Runnable() {
public void run() {
refineGPSAccuracy();
spinnerDialog.dismiss();
return;
}
}).start();
So, essentially, all we’re doing is setting the actual logic aside into its own thread, and once that method returns, dismissing the spinner (as the work is done, and the user should be able to interact with the app again), and killing the thread. Simple as that.
You may also be interested in these articles:
Comments
Leave a comment Trackback