Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 谷歌地图API v2上的随机NullPointerException_Java_Android_Google Maps_Android Fragments - Fatal编程技术网

Java 谷歌地图API v2上的随机NullPointerException

Java 谷歌地图API v2上的随机NullPointerException,java,android,google-maps,android-fragments,Java,Android,Google Maps,Android Fragments,我一直在我的Android应用程序上使用Google Maps API v2(版本3.2.25(761454-30)),有时它工作得很好,但有时(每次都越来越频繁)我会遇到NullPointerException。我在地图上没有做什么太大的改变,在一些Nexus4和NexusS上也发生过。我在GMAPSAPI问题项目上找到了一个解决方案,尽管我没有从那里得到任何帮助。我在这里提出一个问题,然后附上一些细节,看看是否有人已经经历过这件事 正如我所说,我没有做任何与他们在API上建议的不同的事情,我

我一直在我的Android应用程序上使用Google Maps API v2(版本3.2.25(761454-30)),有时它工作得很好,但有时(每次都越来越频繁)我会遇到NullPointerException。我在地图上没有做什么太大的改变,在一些Nexus4和NexusS上也发生过。我在GMAPSAPI问题项目上找到了一个解决方案,尽管我没有从那里得到任何帮助。我在这里提出一个问题,然后附上一些细节,看看是否有人已经经历过这件事

正如我所说,我没有做任何与他们在API上建议的不同的事情,我认为我可能做的唯一不是每个人都必须做的事情(这可能会导致一些问题,idk)是:

  • 我在另一个片段(也称为嵌套片段)中使用SupportMapFragment。我还使用了ActionBar Sherlock,所以另一个片段就是Sherlock片段
  • 我正在片段的onCreateView上实例化SupportMapFragment(而不是将其放在XML上),然后将其添加到布局上的FrameLayout中
  • 我正在对地图应用一些Y平移(使用NineoldAroids),这样我可以获得接近Foursquare应用程序的效果(尽管我从未在Foursquare上获得过NPE)
  • 随着用户在应用程序上的进展,我正在创建并清除一些标记(不应该是这样,因为错误发生在启动时,加载framgent时)
就是这么多,我不会把代码放在这里,因为它不像是一个不起作用的片段,但我已经列出了我正在做的很多事情。这是堆栈跟踪(实际上总是一样的):

嗯,我设法“解决”了这个问题。这实际上不是一个修复,但至少我避免了在抛出异常时应用程序崩溃。我所做的是覆盖默认的未捕获异常处理程序,并在未捕获异常为此异常时禁止应用程序崩溃。崩溃是因为NullPointerException,并且它总是发生在GLThread上(必须来自Google Maps的绘图代码)。因此,我检查是否所有的先决条件都适用,如果适用,我会发送一个带有自定义操作的广播,这样我就可以在我使用谷歌地图的片段上收听该广播,并在我获得一个SupportMapFragment时替换我的SupportMapFragment。由于我们得到了一个未捕获的异常,GLThread被中断,Google-Maps片段的绘制被挂起,因此我们确实需要替换Google-Maps片段以使该映射再次工作

以下是我必须添加的代码:

在我的应用程序的onCreate上:

final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (ex instanceof NullPointerException && thread.getName().startsWith("GLThread")) {
            for (StackTraceElement stackTraceElement : ex.getStackTrace()) {
                if (stackTraceElement.getClassName().contains("maps")) {
                    sendBroadcast(new Intent(ACTION_MAPS_NPE));
                    return;
                }
            }
        }
        defaultHandler.uncaughtException(thread, ex);
    }
});
然后在我使用Google Maps片段的片段上,我在将SupportMapFragment添加到onCreateView上的布局之前注册了这个广播接收器(并在onDestroyView上注销它):


希望这能帮助有同样问题的人。如果有人对它有实际的修复方法,请告诉我。

仅供参考,android中没有google maps api v3,它目前位于v2Sorry,因为版本名的缘故,认为它是v3。修正了。有没有办法修正这个异常???@Zoya检查我下面的答案。人们还针对存储库中的问题给出了一些可能的原因/修复方法:这是一个很好的解决方法,因为我们只能这样做。我只想把它改为使用事件总线而不是广播。你是对的,广播可能是一种过分的行为,甚至是不恰当的行为。我修改了代码,改为使用本地广播管理器,以便广播不会离开我的进程/应用程序。使用事件总线会增加创建register/unregister方法的开销,因为我还没有将任何事件总线库包括到我的项目中,并且从上下文到应用程序类进行了一些转换,所以我认为只使用广播会更干净,尽管使用本地广播。
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (ex instanceof NullPointerException && thread.getName().startsWith("GLThread")) {
            for (StackTraceElement stackTraceElement : ex.getStackTrace()) {
                if (stackTraceElement.getClassName().contains("maps")) {
                    sendBroadcast(new Intent(ACTION_MAPS_NPE));
                    return;
                }
            }
        }
        defaultHandler.uncaughtException(thread, ex);
    }
});
private class GoogleMapsNPEReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Fragment mapFragment = getChildFragmentManager().findFragmentById(R.id.map_fragment_container);
        if (mapFragment != null) {
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.map_fragment_container, SupportMapFragment.newInstance())
                    .commit();
            mMapInitialized = false;
            // We won't have onResume to initialize our map anymore. Try to initialize it after 100ms.
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (getGoogleMap() == null) {
                        handler.postDelayed(this, 100);
                    }
                }
            }, 100);
        }
    }
}