Android 正在等待调用onMapReady()

Android 正在等待调用onMapReady(),android,google-maps,google-maps-android-api-2,Android,Google Maps,Google Maps Android Api 2,我用通常的方式实现了一个GoogleMap,调用MapFragment的getMapAsync(),然后等待调用onMapReady()来提供GoogleMap实例。在我添加代码等待调用onMapReady()之前,这一切都可以正常工作,以确保GoogleMap实例在继续之前可用 从getMapAsync()返回到调用onMapReady()之间有一段很短的时间(有意义——否则就不需要异步)。尽管在我的非正式测试中,延迟往往小于半秒,但我希望处理延迟可能更长的情况 考虑到这个目标,我添加了一个简

我用通常的方式实现了一个GoogleMap,调用MapFragment的getMapAsync(),然后等待调用onMapReady()来提供GoogleMap实例。在我添加代码等待调用onMapReady()之前,这一切都可以正常工作,以确保GoogleMap实例在继续之前可用

从getMapAsync()返回到调用onMapReady()之间有一段很短的时间(有意义——否则就不需要异步)。尽管在我的非正式测试中,延迟往往小于半秒,但我希望处理延迟可能更长的情况

考虑到这个目标,我添加了一个简单的等待循环来阻止一个名为“map_ready”的变量。map_ready最初为false,并由onMapReady()设置为true。waitForGoogleMap()方法只是循环,定期测试变量,只有当变量变为true时才返回。下面是代码大纲

    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;
        }
        [...]
    }
上面显示的代码一遍又一遍地打印出“等待GoogleMap…”——运行waitForGoogleMap()似乎可以防止调用onmaReady()。如果我注释掉对waitForGoogleMap()的调用,它运行得很好

我做错了什么


更新/澄清:我认为我面临的核心问题是,我想监听一个事件,该事件预计将与侦听器发生在同一线程上。在本例中,waitForGoogleMap()正在等待事件“onMapReady()called”,两者都在主线程上

我假设onMapReady()之类的回调是通过创建一个工作线程来实现的,该线程执行必要的腿部工作,然后调用主线程的处理程序将回调(例如onMapReady())添加到主线程的消息队列中。另外,当我从主线程调用wait()时,主线程的循环器将借此机会从其队列中排除另一项

但显然我错了:-)

底线:在onMapReady()执行之前如何阻止?


谢谢, 巴里

另外,上面是我代码的简化版本。实现OnMapReadyCallback(以及onMapReady()回调)的包含类实际上是一个单例。实例是使用instance()方法创建的,随后通过单独的getInstance()方法获取实例。一旦工作正常,我将在getInstance()方法中调用waitForGoogleMap()。这样,应用程序在绝对需要时才会被阻止

我做错了什么

waitForGoogleMap()
运行在本应调用
onmaReady()
的同一线程上,因此在
waitForGoogleMap()
返回之前,无法调用
onmaReady()


摆脱
waitForGoogleMap()
。在
onMapReady()
中开始需要
GoogleMap
的工作。如果需要,使用事件总线将“嘿,地图准备好了!”事件发送到其他组件。

谢谢您的回答。当然,我已经在onMapReady()中做了必要的工作——没有问题。但是,想象一下这样一个场景:onMapReady()回调在一两分钟内没有发生。在getMapAsync()调用之后,主UI线程将继续运行,并将快速运行到依赖于应该在onMapReady()中初始化的内容的代码中。当这种情况发生时,我希望阻塞,直到实际调用onMapReady()。尽管在主线程上调用了onMapReady(),但我假设getmapsync()启动的工作将在工作线程上进行。这是错误的吗?@BarryHolroyd:“将很快遇到依赖于应该在onMapReady()中初始化的内容的代码”——那么你的应用程序就有了基本的架构问题。“我想阻止,直到实际调用onMapReady()”——这将成功冻结您的UI并在5秒内触发ANR。这也会让用户想知道为什么你的应用程序有缺陷。“这不正确吗?”--
getmapsync()
在主应用程序线程上被调用。除非有人告诉你,否则一切都会在主应用程序线程上调用。@BarryHolroyd:如果有一些事情在映射准备好之前不能允许用户做,那么在
onMapReady()内部之前不要启用这些选项。
。在此期间使用进度指示器等,允许用户访问应用程序中不需要地图的其他部分。评论不错,谢谢。我开始考虑这个问题了。我觉得我的建筑很好。问题是我的应用程序是100%地图驱动的——事实上,这就是它的不同之处。用户从一张空白地图开始,可以采取的唯一有趣的步骤需要地图。我不太担心ANR——我会在几秒钟左右检查并更新用户,而不是无休止地等待。我想我可以对用户的每一次尝试做出反应,但我更希望有一个进度指示器(正如你所建议的)来指示应用程序正在等待Gmap服务。我仍然不知道为什么我的方法不起作用。在我看来,每当循环器最终执行时,它应该在mapready()上运行;如果是这样的话,我可以通知用户状态(“正在等待谷歌地图服务…”),如果用户没有在合理的时间内做出响应,我最终会发送一条适当的消息超时。