Google Maps API v2上的随机NullPointerException

Vic*_*ias 5 java android google-maps android-fragments

我一直在我的Android应用程序上使用Google Maps API v2(版本3.2.25(761454-30)),有时它虽然有时候工作得很好(每次都经常更多)但我得到的是NullPointerException.我没有做任何与地图有太大不同的事情,它发生在一些Nexus 4和Nexus S上.我发现了gmaps-api-issues项目的一个问题,虽然我没有得到任何帮助那里.我在这里提出问题,然后提供一些细节,看看是否有人已经完成了这个.

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

  • 我在另一个片段中使用了一个SupportMapFragment,也就是一个嵌套片段.我也在使用ActionBar Sherlock,所以其他片段就是SherlockFragment.
  • 我在Fragment的onCreateView上实例化SupportMapFragment(而不是把它放在XML上)然后将它添加到我的布局上的FrameLayout.
  • 我正在将一些Y翻译应用到地图上(使用九折),这样我就可以获得与Foursquare应用程序相近的效果(尽管我从来没有在Foursquare上获得过NPE).
  • 当用户在应用程序上进行时,我正在创建和清除一些标记(不应该是它,因为错误发生在启动时,加载framgent)

这就是它,我不会把代码放在这里,因为它不是它只是一个不起作用的片段,但我已经列出了我正在做的很多事情.这是堆栈跟踪(它总是几乎相同):

java.lang.NullPointerException
at java.nio.ReadWriteDirectByteBuffer.put(ReadWriteDirectByteBuffer.java:137)
at java.nio.ShortToByteBufferAdapter.put(ShortToByteBufferAdapter.java:163)
at maps.z.d.d(Unknown Source)
at maps.z.d.a(Unknown Source)
at maps.aq.a.a(Unknown Source)
at maps.aq.ao.b(Unknown Source)
at maps.aq.ao.a(Unknown Source)
at maps.v.g.a(Unknown Source)
at maps.v.g.b(Unknown Source)
at maps.p.p.l(Unknown Source)
at maps.p.p.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

Vic*_*ias 8

好吧,我设法"修复"了这个问题.它实际上并不是一个修复程序,但至少我会避免在抛出异常时我的应用程序崩溃.我所做的是覆盖默认的未捕获异常处理程序,并禁止在未捕获的异常是这个时崩溃应用程序.崩溃是因为NullPointerException并且它总是发生在GLThread上(必须来自Google Maps的绘图代码).因此,我检查是否所有先决条件都适用,如果是,我发送一个带有自定义操作的广播,这样我就可以在我使用Google Map的片段上收听广播,当我得到一个时替换我的SupportMapFragment.由于我们遇到了未被捕获的异常,因此GLThread被中断并且Google Maps Fragment的绘图被暂停,因此我们需要替换Google Maps Fragment以使地图重新开始工作.

这是我必须添加的代码:

在我的应用程序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);
    }
});
Run Code Online (Sandbox Code Playgroud)

然后在我使用Google Maps Fragment的Fragment上,我在将SupportMapFragment添加到onCreateView上的布局之前注册这个广播接收器(并在onDestroyView上取消注册):

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助任何有同样问题的人.如果有人有实际的解决方法,请告诉我.