I have a Google Map implemented in the usual fashion, calling MapFragment's getMapAsync() and then waiting for onMapReady() to be called to provide the GoogleMap instance. This all works fine until I add code to wait for onMapReady() to be called, to ensure that the GoogleMap instance is available before proceeding.
There is a short stretch of time between getMapAsync() returning and onMapReady() being called (makes sense -- otherwise it wouldn't need to be asynchronous). Although, in my informal testing, the delay tends to be less than half a second, I want to handle situations where the delay might be longer.
With that goal in mind, I added a simple wait loop to block on a variable called "map_ready". map_ready is initially false and it gets set to true by onMapReady(). The waitForGoogleMap() method simply loops, testing the variable periodically and returning only when the variable becomes true. Here's the code outline.
static boolean map_ready = false;
private void init_gmap_fragment(Activity a) {
[...]
MapFragment f_new = new MapFragment();
[...]
f_new.getMapAsync(this);
waitForGoogleMap();
}
synchronized private void waitForGoogleMap() {
while (!map_ready) {
Log.d(LOGTAG, "Waiting for GoogleMap...");
try {
wait(1000);
} catch (Exception e) { Log.d(LOGTAG, "Exception!"); }
}
}
public void onMapReady(GoogleMap gmap) {
try {
this.gmap = gmap;
map_ready = true;
}
[...]
}
The code as shown above prints out "Waiting for GoogleMap..." over and over -- it appears that running waitForGoogleMap() prevents onMapReady() from ever being called. If I comment out the call to waitForGoogleMap(), it runs just fine.
What am I doing wrong?
UPDATE/CLARIFICATION: I think the core issue I'm facing is that I want to listen for an event which is expected to occur on the same thread as the listener. In this case, waitForGoogleMap() is waiting for the event "onMapReady() called" and both are on the main thread.
I am making the assumption that callbacks such as onMapReady() are implemented by creating a worker thread which does the necessary legwork and then calls the main thread's Handler to add the callback (e.g., onMapReady()) to the main thread's MessageQueue. Also, that when I call wait() from the main thread that the main thread's looper will take that opportunity to excecute another item from its queue.
But apparently I'm wrong :-).
Bottom line: How can I block until onMapReady() executes?
Thanks, Barry
P.S. The above is a simplified version of my code. The containing class which implements OnMapReadyCallback (and hence the onMapReady() callback) is actually a singleton. The instance is created with an Instance() method and the instance is subsequently obtained by a separate getInstance() method. Once this is working, I will put the call to waitForGoogleMap() in the getInstance() method. That way the app won't block until it absolutely needs to.