mapbox / mapbox-navigation-android

Mapbox Navigation SDK for Android
https://docs.mapbox.com/android/navigation/overview/
Other
622 stars 318 forks source link

Navigation freezing unexpectedly. #3881

Open peytonwupeixin opened 3 years ago

peytonwupeixin commented 3 years ago

Android API:29 Mapbox Navigation SDK version:1.2.0

Background

https://user-images.githubusercontent.com/63035601/102905117-a4cf1d80-44ad-11eb-93ed-d2072a781854.MP4

1.We have a activity called index page with a com.mapbox.mapboxsdk.maps.MapView and com.mapbox.mapboxsdk.maps.MapboxNavigation for requesting the route.We call com.mapbox.mapboxsdk.maps.MapboxNavigation#onDestroy() at the onDestroy() method of this activity.

2.There is a button with "Ready to go" text on this page.It will start a new activity called navigation page for turn by trun navigation,when this button clicked.

3.Navigation page use com.mapbox.navigation.ui.NavigationView and call startNavigation(NavigationViewOptions options) for navigation.

Steps to trigzger behavior

The index page would be destroied when we are navigating on the naviagation page and device on low memory(We can mock this case with turn on the "Don't keep activities" opiton at device's developer options).

Expected behavior

Navigation work well.

Actual behavior

Our app freezing and the navigation stoped.

My opinion

1:Currently,we can not get access of the com.mapbox.navigation.base.route.Router and its implementation class(MapboxHybridRouter,MapboxOffboardRouter,MapboxOnboardRouter) directly.

2:There is two ways for us to get the route between origin location and destination location.

3:The navigator field in MapboxNavigation instance is the single instance of com.mapbox.navigation.navigator.internal.MapboxNativeNavigatorImpl.It will cause two different instances of MapboxNavigation(one at index page for route ,another created by NaviagationView with com.mapbox.navigation.ui.NavigationViewModel at naviagation page) refer the same MapboxNativeNavigatorImpl.MapboxNativeNavigatorImpl#resetRideSession() called when MapboxNavigation#onDestroy().

4:The index page's MapboxNavigation instance affect the MapboxNavigation instance of NavigationView and case this issue.

LukasPaczos commented 3 years ago

Thanks for reporting the issue @peytonwupeixin. I'm able to reproduce a freeze where location updates stop being delivered when I follow your steps:

  1. Enable "don't keep activities" dev option.
  2. Apply this diff:

    
    diff --git a/examples/src/main/java/com/mapbox/navigation/examples/core/SimpleMapboxNavigationKt.kt b/examples/src/main/java/com/mapbox/navigation/examples/core/SimpleMapboxNavigationKt.kt
    index abc55fda7..9f74d1997 100644
    --- a/examples/src/main/java/com/mapbox/navigation/examples/core/SimpleMapboxNavigationKt.kt
    +++ b/examples/src/main/java/com/mapbox/navigation/examples/core/SimpleMapboxNavigationKt.kt
    @@ -1,6 +1,7 @@
    package com.mapbox.navigation.examples.core
    
    import android.annotation.SuppressLint
    +import android.content.Intent
    import android.os.Bundle
    import android.os.CountDownTimer
    import android.os.Looper
    @@ -56,6 +57,7 @@ import com.mapbox.navigation.core.trip.session.TripSessionStateObserver
    import com.mapbox.navigation.core.trip.session.VoiceInstructionsObserver
    import com.mapbox.navigation.examples.R
    import com.mapbox.navigation.examples.history.HistoryRecorder
    +import com.mapbox.navigation.examples.ui.NavigationViewActivity
    import com.mapbox.navigation.examples.utils.Utils
    import com.mapbox.navigation.examples.utils.Utils.PRIMARY_ROUTE_BUNDLE_KEY
    import com.mapbox.navigation.examples.utils.extensions.toPoint
    @@ -261,14 +263,8 @@ class SimpleMapboxNavigationKt :
     @SuppressLint("MissingPermission")
     private fun initNavigationButton() {
         startNavigation.setOnClickListener {
    -            updateCameraOnNavigationStateChange(true)
    -            mapboxNavigation.registerVoiceInstructionsObserver(this)
    -            mapboxNavigation.startTripSession()
    -            val routes = mapboxNavigation.getRoutes()
    -            if (routes.isNotEmpty()) {
    -                initDynamicCamera(routes[0])
    -            }
    -            navigationMapboxMap.showAlternativeRoutes(false)
    +            val intent = Intent(this, NavigationViewActivity::class.java)
    +            startActivity(intent)
         }
     }

3. Open `SimpleNavigationActivityKt`.
4. Long click to set a route.
5. Click "start navigation"
6. The new activity with `NavigationView` loads frozen. Location updates are not being delivered.

![ezgif com-optimize (100)](https://user-images.githubusercontent.com/16925074/103906775-aaa93d80-5100-11eb-9456-152029471028.gif)
Guardiola31337 commented 3 years ago

Note that as soon as the session starts (and the maps is loaded) the status bar location icon disappears (like the location is disabled by the system somehow) 🤔

benorgan commented 3 years ago

I think we are also seeing this behaviour (or possibly a slightly different but similar issue). When calling startNavigation the first time the route works correctly and the instructions show up in the banner.

However if we call stopNavigation and then startNavigation again (to set a new destination) the instructions do not update and remain "frozen" on the previous instruction. The map does update but the instructions do not.

This screenshot shows the correct instructions when calling startNavigation the first time:

image

But when startNavigation is called again (regardless of whether it's with the same destination / route or a new one) the map updates but the instruction banner does not. Here the "Make a slight right" instruction is shown even though the map shows a left turn onto Oak St.

image

benorgan commented 3 years ago

Update: just fixed this - turns out calling stopNavigation breaks the instructions and isn't needed anyway, you can just call startNavigation again with a new route.

benorgan commented 3 years ago

This is still causing an issue for us as we need to call stopNavigation when we hide the navigation in order to stop the voice notifications continuing. Then when we call startNavigation again for a new trip, the banner and voice instructions do not update and are "stuck" on the previous trip.

It seems that stopNavigation unregisters the bannerInstructionsObserver and voiceInstructionsObserver but these do not get re-registered correctly when calling startNavigation. It looks like the code is there to re-register these (in addNavigationListeners of the NavigationViewModel) but for some reason this isn't working.

We could destroy and re-initialize the navigation here but this seems suboptimal in terms of performance and I suspect might lead to memory leaks.

benorgan commented 3 years ago

As a workaround for this we are replacing the speechAnnouncementListener with one that ignores announcements instead of calling stopNavigation, then when we call startNavigation for a new destination we replace it with the regular speechAnnouncementListener:

[...]
{
  [...]
  optionsBuilder.speechAnnouncementListener(speechAnnouncementListener)
  this.startNavigation(optionsBuilder.build())
}

override fun stopNavigation() {
  optionsBuilder.speechAnnouncementListener(mutedSpeechAnnouncementListener)
  this.startNavigation(optionsBuilder.build())
}

private val mutedSpeechAnnouncementListener = SpeechAnnouncementListener { VoiceInstructions.builder().build() }
private val speechAnnouncementListener = SpeechAnnouncementListener { announcement -> announcement!! }
abhishek1508 commented 2 years ago

Thanks for using the Mapbox Navigation SDK for Android and being a valued customer.

Mapbox will be soon deprecating any support for v0 and v1 versions of the SDK. To facilitate this transition we’re launching a new drop-in UI component into v2, equivalent to the existing NavigationView v1 in its design goals, however with a more modern and customizable API.

We plan to launch this new drop-in UI component as a Developer Preview feature in April, as part of the v2.5 series. Since you are using NavigationView with v1, we’d love to hear your feedback so that we can incorporate it ahead of a GA release.

If you’re interested in having early access to the upcoming drop-in UI for v2 and its documentation, drop a comment on this ticket or send an email to abhishek.kejriwal@mapbox.com

/cc @zugaldia @AhmerKhan1