4

I'm getting the following error during my mapView.getMapAsync{} call:

2019-10-03 19:37:57.605 10964-10964/my.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: my.app, PID: 10964
    java.lang.IllegalStateException: Calling getSourceAs when a newer style is loading/has loaded.
        at com.mapbox.mapboxsdk.maps.Style.validateState(Style.java:584)
        at com.mapbox.mapboxsdk.maps.Style.getSourceAs(Style.java:131)
        at com.mapbox.mapboxsdk.location.LocationLayerController.refreshSource(LocationLayerController.java:292)
        at com.mapbox.mapboxsdk.location.LocationLayerController.setLocationPoint(LocationLayerController.java:302)
        at com.mapbox.mapboxsdk.location.LocationLayerController.access$000(LocationLayerController.java:61)
        at com.mapbox.mapboxsdk.location.LocationLayerController$1.onNewAnimationValue(LocationLayerController.java:422)
        at com.mapbox.mapboxsdk.location.LocationLayerController$1.onNewAnimationValue(LocationLayerController.java:418)
        at com.mapbox.mapboxsdk.location.MapboxAnimator.postUpdates(MapboxAnimator.java:83)
        at com.mapbox.mapboxsdk.location.MapboxAnimator.onAnimationUpdate(MapboxAnimator.java:71)
        at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1547)
        at android.animation.ValueAnimator.setCurrentFraction(ValueAnimator.java:674)
        at android.animation.ValueAnimator.setCurrentPlayTime(ValueAnimator.java:637)
        at android.animation.ValueAnimator.start(ValueAnimator.java:1069)
        at android.animation.ValueAnimator.start(ValueAnimator.java:1088)
        at android.animation.ValueAnimator.startWithoutPulsing(ValueAnimator.java:1081)
        at android.animation.AnimatorSet.handleAnimationEvents(AnimatorSet.java:1142)
        at android.animation.AnimatorSet.startAnimation(AnimatorSet.java:1227)
        at android.animation.AnimatorSet.start(AnimatorSet.java:729)
        at android.animation.AnimatorSet.start(AnimatorSet.java:684)
        at com.mapbox.mapboxsdk.location.MapboxAnimatorSetProvider.startAnimation(MapboxAnimatorSetProvider.java:30)
        at com.mapbox.mapboxsdk.location.LocationAnimatorCoordinator.playAnimators(LocationAnimatorCoordinator.java:294)
        at com.mapbox.mapboxsdk.location.LocationAnimatorCoordinator.feedNewLocation(LocationAnimatorCoordinator.java:97)
        at com.mapbox.mapboxsdk.location.LocationComponent.updateLocation(LocationComponent.java:1317)
        at com.mapbox.mapboxsdk.location.LocationComponent.access$1000(LocationComponent.java:94)
        at com.mapbox.mapboxsdk.location.LocationComponent$CurrentLocationEngineCallback.onSuccess(LocationComponent.java:1473)
        at com.mapbox.mapboxsdk.location.LocationComponent$CurrentLocationEngineCallback.onSuccess(LocationComponent.java:1461)
        at com.mapbox.android.core.location.GoogleLocationEngineImpl$GoogleLocationEngineCallbackTransport.onLocationResult(GoogleLocationEngineImpl.java:114)
        at com.google.android.gms.internal.location.zzau.notifyListener(Unknown Source:4)
        at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:17)
        at com.google.android.gms.common.api.internal.ListenerHolder$zaa.handleMessage(Unknown Source:5)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at com.google.android.gms.internal.base.zap.dispatchMessage(Unknown Source:8)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6702)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)

Here is my code:

MapFragment.kt

var symbolOptions = SymbolOptions()
private var symbolManager: SymbolManager? = null
private var mapView: MapView? = null
private lateinit var mapboxMap: MapboxMap
private var navigationMapRoute: NavigationMapRoute? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    /** Initialise Mapbox **/
    mapView = view.findViewById(R.id.mapView)
    mapView?.onCreate(savedInstanceState)
    val destinationMarker = ContextCompat.getDrawable(activity, R.drawable.logo) ?: return
    mapView?.getMapAsync { mapboxMap ->
        Log.d("getMapAsync") // this doesn't print 
        this.mapboxMap = mapboxMap
        this.mapboxMap.setStyle(Style.MAPBOX_STREETS) { style ->
            style.addImage("destination", destinationMarker)
            showUserLocation(style)
            resetCamera()
        }
    }
}

Unfortunately I don't understand the error message Calling getSourceAs when a newer style is loading/has loaded. This is the initial load of the map style so I'm not sure why it's telling me I'm trying to change the style.

What does the error mean and how can I fix it?

Zorgan
  • 8,227
  • 23
  • 106
  • 207

3 Answers3

1

Simply use:

 mapboxMap.getStyle(new Style.OnStyleLoaded() {
            @Override
            public void onStyleLoaded(@NonNull Style style) {
                // Continue your job here

            }
        });
Iman Marashi
  • 5,593
  • 38
  • 51
0

You've got the crash coming after an animation:

at com.mapbox.mapboxsdk.location.LocationAnimatorCoordinator.playAnimators(LocationAnimatorCoordinator.java:294)
at com.mapbox.mapboxsdk.location.LocationAnimatorCoordinator.feedNewLocation(LocationAnimatorCoordinator.java:97)
at com.mapbox.mapboxsdk.location.LocationComponent.updateLocation(LocationComponent.java:1317)
at com.mapbox.mapboxsdk.location.LocationComponent.access$1000(LocationComponent.java:94)
at com.mapbox.mapboxsdk.location.LocationComponent$CurrentLocationEngineCallback.onSuccess(LocationComponent.java:1473)
at com.mapbox.mapboxsdk.location.LocationComponent$CurrentLocationEngineCallback.onSuccess(LocationComponent.java:1461)
at com.mapbox.android.core.location.GoogleLocationEngineImpl$GoogleLocationEngineCallbackTransport.onLocationResult(GoogleLocationEngineImpl.java:114)

For me crashes after animations are always a clue that something lifecycle related is going wrong. Mapbox is probably trying to do something after the animation completes and doesn't know that your activity/fragment is in a different state. You can try to debug by turning on "Don't Keep Activities" in Developer Options.

For my case, a little breadcrumb logs + debugger and I realized this was happening after leaving an activity, after onDestroy() was called. Mapbox is pretty good at checking lifecycle inside its own code, otherwise there would be lots of these "crashed after animation" bugs, since Mapbox is full of animations. I did some further looking and sure enough I was missing my call to MapView.onStop(). I had the other lifecycle methods except this one:

override fun onStop() {
    super.onStop()
    mapView.onStop()
}
``
tir38
  • 9,810
  • 10
  • 64
  • 107
0

Those of you dealing with this issue in Flutter (mapbox_gl: ^0.16.0 at the time of this writing) may benefit from this approach:

  1. Set a bool when changing the style string at run time:
void changeToSatelliteView() {
  mapStyleNotLoaded = true;
  yourStyleString = MapboxStyles.SATELLITE;
}
  1. Make sure you reference that same style sheet variable when you build the map using styleString: yourStyleString.

  2. Also in build, make sure you have the onStyleLoadedCallback: onStyleLoaded to reference a function where you can reset that flag and then do your fancy MapBox stuff:

void onStyleLoaded() {
  mapStyleNotLoaded = false;
  doFancyMapBoxStuff();
}

  1. Don't do your fancy MapBox stuff if the style has not yet reloaded:
void doFancyMapBoxStuff() async {
  if (mapStyleNotLoaded) return;
  mapController.addCircle( ... );
  ...
}

Weirdly for me this issue is limited to Android. Perhaps the web and iOS devices I am testing with have slower processors.