maps: Race race condition if prop is set before styleURL is loaded results in a crash
Describe the bug Race race condition which is happening when <MapboxGL.Camera followUserMode=“course”> prop is set before styleURL is loaded results in a crash on Android. Happens intermittently because sometimes network is faster than rendering.
To Reproduce
<MapboxGL.MapView
animated
ref={c => this.map = c}
styleURL={this.props.theme.styleURL}
onUserLocationUpdate={this.onUserLocationUpdate}
onPress={this.onPress}
onLongPress={this.onPress}
logoEnabled={false}
compassEnabled={false}
pitchEnabled={false}
onRegionWillChange={this.onRegionWillChange}
style={{ flex: 1 }}
onDidFinishLoadingMap={this.onDidFinishLoadingMap}
onDidFinishRenderingMap={this.onDidFinishRenderingMap}
onDidFinishRenderingMapFully={this.onDidFinishRenderingMapFully}
onDidFinishLoadingStyle={this.onDidFinishLoadingStyle}
>
<MapboxGL.Camera
followUserLocation={this.state.currentTrackingModeIsFollowing}
followUserMode="course"
onUserTrackingModeChange={this.onUserTrackingModeChange}
/>
</MapboxGL.MapView>
Expected behavior Not to crash
Versions (please complete the following information):
- Platfrom: Android
- Device: Pixel 2
- OS: Android API 27
- SDK Version: I’m using commit id ee78a67e13c27b2258a53849282bc07b5ebc374c
- React Native Version 0.60.5
Additional context Stack trace
2019-08-28 18:59:21.455 22671-22671/com.myverycoolapp E/unknown:ViewManager: Error while updating prop followUserLocation
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:131)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:51)
at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:46)
at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NullPointerException: Style in LocationComponentActivationOptions is null. Make sure the Style object isn't null. Wait for the map to fully load before passing the Style object to LocationComponentActivationOptions.
at com.mapbox.mapboxsdk.location.LocationComponentActivationOptions$Builder.build(LocationComponentActivationOptions.java:229)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.updateLocationLayer(RCTMGLCamera.java:380)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.setUserTrackingMode(RCTMGLCamera.java:491)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.updatedFollowUserMode(RCTMGLCamera.java:510)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.setFollowUserLocation(RCTMGLCamera.java:498)
at com.mapbox.rctmgl.components.camera.RCTMGLCameraManager.setFollowUserLocation(RCTMGLCameraManager.java:66)
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:131)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:51)
at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:46)
at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
2019-08-28 18:59:21.460 22671-22671/com.myverycoolapp E/unknown:ReactNative: Exception in native call
com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'followUserLocation' of a view managed by: RCTMGLCamera
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:98)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:131)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:51)
at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:46)
at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:131)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:51)
at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:46)
at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NullPointerException: Style in LocationComponentActivationOptions is null. Make sure the Style object isn't null. Wait for the map to fully load before passing the Style object to LocationComponentActivationOptions.
at com.mapbox.mapboxsdk.location.LocationComponentActivationOptions$Builder.build(LocationComponentActivationOptions.java:229)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.updateLocationLayer(RCTMGLCamera.java:380)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.setUserTrackingMode(RCTMGLCamera.java:491)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.updatedFollowUserMode(RCTMGLCamera.java:510)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.setFollowUserLocation(RCTMGLCamera.java:498)
at com.mapbox.rctmgl.components.camera.RCTMGLCameraManager.setFollowUserLocation(RCTMGLCameraManager.java:66)
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:131)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:51)
at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:46)
at com.facebook.react.uimanager.NativeViewHierarchyManager.updateProperties(NativeViewHierarchyManager.java:139)
at com.facebook.react.uimanager.UIViewOperationQueue$UpdatePropertiesOperation.execute(UIViewOperationQueue.java:93)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
2019-08-28 18:59:21.519 22671-22671/com.myverycoolapp D/LocationManager: Tick [174.762890, -36.849760]
2019-08-28 18:59:21.519 22671-22671/com.myverycoolapp D/LocationManager: Listener count 1
2019-08-28 18:59:21.568 1435-1471/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 6742016
2019-08-28 18:59:21.598 1445-1445/? D/SurfaceFlinger: duplicate layer name: changing com.myverycoolapp/com.myverycoolapp.MainActivity to com.myverycoolapp/com.myverycoolapp.MainActivity#1
2019-08-28 18:59:21.603 1435-1471/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 8298496
2019-08-28 18:59:21.617 1435-1471/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 8298496
2019-08-28 18:59:21.624 1435-14292/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 8298496
2019-08-28 18:59:21.625 22671-23004/com.myverycoolapp V/Mbgl-HttpRequest: [HTTP] Request was successful (code = 200).
2019-08-28 18:59:21.713 22671-22671/com.myverycoolapp E/Mbgl-MapChangeReceiver: Exception in onDidFinishLoadingStyle
com.mapbox.mapboxsdk.location.LocationComponentNotInitializedException: The LocationComponent has to be activated with one of the LocationComponent#activateLocationComponent overloads before any other methods are invoked.
at com.mapbox.mapboxsdk.location.LocationComponent.checkActivationState(LocationComponent.java:1546)
at com.mapbox.mapboxsdk.location.LocationComponent.setLocationComponentEnabled(LocationComponent.java:490)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.updateLocationLayer(RCTMGLCamera.java:385)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.enableLocationComponent(RCTMGLCamera.java:342)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera.access$900(RCTMGLCamera.java:49)
at com.mapbox.rctmgl.components.camera.RCTMGLCamera$5.onStyleLoaded(RCTMGLCamera.java:335)
at com.mapbox.mapboxsdk.maps.MapboxMap.notifyStyleLoaded(MapboxMap.java:852)
at com.mapbox.mapboxsdk.maps.MapboxMap.onFinishLoadingStyle(MapboxMap.java:208)
at com.mapbox.mapboxsdk.maps.MapView$MapCallback.onDidFinishLoadingStyle(MapView.java:1215)
at com.mapbox.mapboxsdk.maps.MapChangeReceiver.onDidFinishLoadingStyle(MapChangeReceiver.java:196)
at com.mapbox.mapboxsdk.maps.NativeMapView.onDidFinishLoadingStyle(NativeMapView.java:1035)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Workaround:
onDidFinishLoadingStyle = (e) => {
console.log('onDidFinishLoadingStyle', e)
this.setState({hasFinishedLoadingStyle:true})
};
<MapboxGL.MapView
onDidFinishLoadingStyle={this.onDidFinishLoadingStyle}
>
{this.state.hasFinishedLoadingStyle ?
<MapboxGL.Camera
followUserLocation={this.state.currentTrackingModeIsFollowing}
followUserMode="course"
onUserTrackingModeChange={this.onUserTrackingModeChange}
/>
: null
}
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 3
- Comments: 27 (16 by maintainers)
hey @dorthwein, I can totally relate - however, we have very limited resources here 😞,
especially with something that goes deep into native territory we need the support of the community and that means:
I have a hunch this PR could fix this issue.
https://github.com/react-native-mapbox-gl/maps/pull/1619
For those of you who see this bug, the above strategies of wrapping user & camera components in render checks has done tons to decrease the frequency of this bug for us in production, however it does still happen from time to time.
If anyone else runs into this issue something that has worked for us is wrapping the camera in the following.
Just make sure if you allow the user to change the MapStyleURL in any way, that you are first un mounting the camera by setting finishedLoadingStyle to false, then resetting it too true once it has reloaded.