Random NullPointerException in Google Maps API v2

I work with the Google Maps API v2 (version 3.2.25 (761454-30)) in my Android application, and sometimes it works fine, although sometimes (which appears more often each time). I get a null pointer exception. I do nothing else with the card, and this happened on some Nexus 4, as well as on Nexus S. I found the issue in the gmaps-api-issues project, although I don't get any help from it. Then I ask a question with some details to find out if someone has gone through this.

As I said, I do nothing else than what they offer in the API, and the only thing I think can do is that not everyone does (and this may cause some problem, idk)

  • I am using SupportMapFragment inside another fragment, aka as a nested fragment. I also use the ActionBar Sherlock, so another snippet is a SherlockFragment, to just say.
  • I create an instance of SupportMapFragment on my onCreateView snippet (instead of putting it in XML) and then add it to FrameLayout on my layout.
  • I apply some translation of Y to the map (with nine rings) so that I can get an effect similar to that in the Foursquare app (although I never had an NPE on Foursquare).
  • I create and clear some markers as the user works in the application (this should not be so, since the error occurs when starting when loading the framegang)

That's all, I won’t enter the code here, because it’s not just a fragment that does not work, but I have listed a lot of what I am doing. Here is the stack trace (it is always almost the same):

java.lang.NullPointerException at java.nio.ReadWriteDirectByteBuffer.put(ReadWriteDirectByteBuffer.java:137) at java.nio.ShortToByteBufferAdapter.put(ShortToByteBufferAdapter.java:163) at maps.zdd(Unknown Source) at maps.zda(Unknown Source) at maps.aq.aa(Unknown Source) at maps.aq.ao.b(Unknown Source) at maps.aq.ao.a(Unknown Source) at maps.vga(Unknown Source) at maps.vgb(Unknown Source) at maps.ppl(Unknown Source) at maps.pprun(Unknown Source) 
+4
source share
1 answer

Well, I managed to "fix" this problem. This is not really a fix, but at least I avoid a crash in my application when this exception is thrown. What I did was to override the default exception thrower and suppress the application crash when it is an uncaught exception. The accident occurred due to a NullPointerException exception, and this always happened on GLThread (must be from a drawing code from Google Maps). So I check if all the preconditions apply, and if so, I send a broadcast with a custom action so that I can listen to this broadcast on the snippet on which I use the Google Map, replacing my SupportMapFragment when I receive it. Since we have an uncaught exception, GLThread is aborted and the drawing in the Google Map Fragment is paused, so we need to replace the Google Maps fragment to make the map work again.

Here is the code I had to add:

In my onCreate app:

 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); } }); 

And then on my snippet that uses the Google Maps snippet, I will register this broadcast receiver right before adding SupportMapFragment to the layout on onCreateView (and unregister on 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); } } } 

Hope this helps someone with the same issue. If anyone has the actual fix, let me know.

+7
source

Source: https://habr.com/ru/post/1492790/


All Articles