@@ -81,6 +81,7 @@ public class NavModule extends NativeNavModuleSpec
8181 private Navigator .TrafficUpdatedListener mTrafficUpdatedListener ;
8282 private Navigator .ReroutingListener mReroutingListener ;
8383 private Navigator .RemainingTimeOrDistanceChangedListener mRemainingTimeOrDistanceChangedListener ;
84+ private Observer <NavInfo > mNavInfoObserver ;
8485
8586 private @ Navigator .TaskRemovedBehavior int taskRemovedBehaviour =
8687 Navigator .TaskRemovedBehavior .CONTINUE_SERVICE ;
@@ -174,15 +175,22 @@ public void cleanup(final Promise promise) {
174175 }
175176
176177 final Navigator navigator = mNavigator ;
178+
177179 UiThreadUtil .runOnUiThread (
178180 () -> {
179181 // Remove listeners on UI thread to serialize with callback dispatch.
180182 // This reduces the chance of triggering a race condition in the Navigation SDK
181183 // where callbacks may still be in-flight during removal.
182184 removeLocationListener ();
183185 removeNavigationListeners ();
184- navigator .clearDestinations ();
186+ removeNavInfoObserver ();
187+ // Null out fields after listener removal so the removal methods
188+ // can still access mNavigator and mRoadSnappedLocationProvider.
189+ mNavigator = null ;
190+ mRoadSnappedLocationProvider = null ;
191+ NavForwardingManager .stopNavForwarding (navigator , this );
185192 navigator .stopGuidance ();
193+ navigator .clearDestinations ();
186194 navigator .getSimulator ().unsetUserLocation ();
187195 promise .resolve (true );
188196 });
@@ -279,14 +287,15 @@ public void initializeNavigationSession(
279287 initializeNavigationApi ();
280288
281289 // Observe live data for nav info updates.
282- Observer <NavInfo > navInfoObserver = this ::showNavInfo ;
283-
290+ // Remove any existing observer first to prevent duplicates after cleanup+reinit cycles.
284291 UiThreadUtil .runOnUiThread (
285292 () -> {
293+ removeNavInfoObserver ();
294+ mNavInfoObserver = this ::showNavInfo ;
286295 final Activity currentActivity = getReactApplicationContext ().getCurrentActivity ();
287296 if (currentActivity != null ) {
288297 NavInfoReceivingService .getNavInfoLiveData ()
289- .observe ((LifecycleOwner ) currentActivity , navInfoObserver );
298+ .observe ((LifecycleOwner ) currentActivity , mNavInfoObserver );
290299 }
291300 });
292301 }
@@ -418,7 +427,7 @@ public void setTurnByTurnLoggingEnabled(boolean isEnabled) {
418427 if (isEnabled ) {
419428 NavForwardingManager .startNavForwarding (mNavigator , currentActivity , this );
420429 } else {
421- NavForwardingManager .stopNavForwarding (mNavigator , currentActivity , this );
430+ NavForwardingManager .stopNavForwarding (mNavigator , this );
422431 }
423432 }
424433
@@ -528,6 +537,13 @@ private void removeNavigationListeners() {
528537 }
529538 }
530539
540+ private void removeNavInfoObserver () {
541+ if (mNavInfoObserver != null ) {
542+ NavInfoReceivingService .getNavInfoLiveData ().removeObserver (mNavInfoObserver );
543+ mNavInfoObserver = null ;
544+ }
545+ }
546+
531547 private void createWaypoint (Map map ) {
532548 String placeId = CollectionUtil .getString ("placeId" , map );
533549 String title = CollectionUtil .getString ("title" , map );
0 commit comments