eopeter / flutter_mapbox_navigation

Turn By Turn Navigation for Your Flutter Application
Apache License 2.0
213 stars 180 forks source link

i have a driving app that use google_maps and mapbox navigation as a navigation map but my app crash when the mapbox navigation is called 3 times #269

Open XxMenotoxX opened 1 year ago

XxMenotoxX commented 1 year ago

here is the the error i get

FATAL EXCEPTION: main
E/AndroidRuntime(26642): Process: com.example.delivery_app, PID: 26642
E/AndroidRuntime(26642): java.lang.NullPointerException: Missing required view with ID: com.example.delivery_app:id/maneuverView
E/AndroidRuntime(26642):    at com.mapbox.navigation.dropin.databinding.MapboxManeuverGuidanceLayoutBinding.bind(MapboxManeuverGuidanceLayoutBinding.java:60)
E/AndroidRuntime(26642):    at com.mapbox.navigation.dropin.maneuver.ManeuverViewBinder.bind(ManeuverViewBinder.kt:27)
E/AndroidRuntime(26642):    at com.mapbox.navigation.dropin.maneuver.ManeuverViewBinder.bind(ManeuverViewBinder.kt:16)
E/AndroidRuntime(26642):    at com.mapbox.navigation.ui.base.lifecycle.UICoordinator$onAttached$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:136)
E/AndroidRuntime(26642):    at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$$inlined$combineUnsafe$FlowKt__ZipKt$1$2.invokeSuspend(Zip.kt:333)
E/AndroidRuntime(26642):    at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$$inlined$combineUnsafe$FlowKt__ZipKt$1$2.invoke(Unknown Source:13)
E/AndroidRuntime(26642):    at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$$inlined$combineUnsafe$FlowKt__ZipKt$1$2.invoke(Unknown Source:6)
E/AndroidRuntime(26642):    at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt:79)
E/AndroidRuntime(26642):    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
E/AndroidRuntime(26642):    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
E/AndroidRuntime(26642):    at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime(26642):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(26642):    at android.os.Looper.loopOnce(Looper.java:211)
E/AndroidRuntime(26642):    at android.os.Looper.loop(Looper.java:300)
E/AndroidRuntime(26642):    at android.app.ActivityThread.main(ActivityThread.java:8322)
E/AndroidRuntime(26642):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(26642):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
E/AndroidRuntime(26642):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1038)
E/AndroidRuntime(26642):    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@8c69d01, Dispatchers.Main]
W/le.delivery_app(26642): type=1400 audit(0.0:24965): avc: denied { search } for name="mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
W/OOMEventManagerFK(26642): Failed to mkdir /data/mqsas/hprof/
W/System  (26642): A resource failed to call close.
W/le.delivery_app(26642): type=1400 audit(0.0:24966): avc: denied { search } for name="mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
W/le.delivery_app(26642): type=1400 audit(0.0:24967): avc: denied { search } for name="mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
W/le.delivery_app(26642): type=1400 audit(0.0:24968): avc: denied { search } for name="mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
W/le.delivery_app(26642): type=1400 audit(0.0:24969): avc: denied { getattr } for path="/data/mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
W/le.delivery_app(26642): type=1400 audit(0.0:24970): avc: denied { search } for name="mqsas" dev="sda11" ino=211 scontext=u:r:untrusted_app:s0:c223,c258,c512,c768 tcontext=u:object_r:mqsas_data_file:s0 tclass=dir permissive=0 app=com.example.delivery_app
I/Process (26642): Sending signal. PID: 26642 SIG: 9
Lost connection to device.
ddiegosousa commented 10 months ago

@codenomaddev vamos https://meet.google.com/vcq-vmfo-hzh 17:30?

codenomaddev commented 10 months ago

@marciotisouza e @ddiegosousa vamos sim agora as 17:30 no chat

marciotisouza commented 10 months ago

Certo, combinado !!!

Mohammed-Alekhwan commented 10 months ago

@marciotisouza @codenomaddev @ddiegosousa Have you guys found any solution of the problem in your meeting?

Rakan-Makhashin commented 10 months ago

is there any other turn by turn navigation solutions i can use ?

marciotisouza commented 10 months ago

@Mohammed-Alekhwan Not yet, we are researching !!!

marciotisouza commented 10 months ago

@AVroku92 the problem is only in the Embedded option, the normal option is working.

reubendeekay commented 9 months ago

Did you find a workaround? @eopeter @marciotisouza @AVroku92

rickylaw-dh commented 9 months ago

I have the same problem. I found the embedded view can build the route many many times without crash

BUT, if I call the controller to startNavigation() when receive the RouteEvent.eventType == MapBoxEvent.route_built

It will crash when I have to start navigation around 2-3 times

Hope this can help...

eopeter commented 9 months ago

Does it crash right after you get the route_built event or when the navigation begins?

rickylaw-dh commented 9 months ago

It should be crash on navigation begins route_built event will not crash

rickylaw-dh commented 9 months ago

@eopeter I watched your video https://www.youtube.com/watch?v=-q8gwWmGdRM What is the button click step?

Build Route > Start > ? > Build Route > Start > ? > etc

I am now trying to use the GlobalKey and AutomaticKeepAliveClientMixin The result is the Map will only create one, and the route can draw But the navigation will not start even when I invoked startNavigation() It will keep firing event navigation_cancel

More interesting are,

  1. The ManeuverView will not have any information inside when manuelly click the bottom start navigation button in the MapView
  2. The clearRoute() and startFreeDrive() will not return anything if I use "await", so that I cannot clearRoute() if I keep the widget alive

(And sometimes I get a memory leak...πŸ˜‚

I hope this can help to investigate πŸ™πŸ»

reubendeekay commented 9 months ago

@eopeter Could you please look into this issue. We would really appreciate it?

rickylaw-dh commented 9 months ago

hmmmm... Finally, my app did not crash and I could have many times to start the route and navigation

In my case:

  1. I have a wrapper stateful widget to contain the embedded view
  2. The wrapper widget has a const constructor with a key
  3. The main app widget has a GlobalKey to point the wrapper widget state
  4. The wrapper widget in the main app widget's build() will not have any remove logic (e.g.: if (showNavigation) ... { })
  5. I have copied the MapBoxNavigationViewController & MapBoxNavigationView and custom the MapBoxNavigationViewController to fix duplicate listen "_streamRouteEvent!.listen(_onProgressData);" at startRoute()

Now, I can show the route and start the navigation

BUT.............. the ManeuverView is blank....... I found that there should be no event from MapBoxEvent.progress_change

I have no idea why I call "_controller?.finishNavigation();" and it return true Then, the MapBoxEvent.progress_change will not receive any more..... (** If call "_controller?.clearRoute()" before "_controller?.finishNavigation()", finishNavigation() will return false....

@eopeter, is my usage problem??

rickylaw-dh commented 9 months ago

I tested with version 0.2.0 but the problem is the same, after finishing the route it keeps working and sending information, even leaving the screen it was on and returning to the app's main screen it continues transmitting information. See below that it has finished the route section and continues arriving in the MapBoxEvent.progress_change method

currentLegDistanceRemaining: 0.0 W/Mapbox (30124): [nav-native]: Using the same old location with timestamp = 858841291852758ns, lng = -46.502187, lat = -23.430765 for 10 seconds E/Mapbox (30124): [nav-sdk]: [MapboxFollowingFrameProcessor] Start position is beyond line

When you return to the main screen of the app, it sends the message below, one after the other:

E/Mapbox (30124): [nav-sdk]: [MapboxFollowingFrameProcessor] Start position is beyond line I/stem.br_expres(30124): Explicit concurrent copying GC freed 5579(287KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 8693KB/16MB, paused 303us total 89.885ms two E/Mapbox (30124): [nav-sdk]: [MapboxFollowingFrameProcessor] Start position is beyond line W/Mapbox (30124): [nav-native]: Using the same old location with timestamp = 858841291852758ns, lng = -46.502187, lat = -23.430765 for 80 seconds E/Mapbox (30124): [nav-sdk]: [MapboxFollowingFrameProcessor] Start position is beyond line I/stem.br_expres(30124): Explicit concurrent copying GC freed 5582(304KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 8741KB/17MB, paused 584us total 106.255ms two E/Mapbox (30124): [nav-sdk]: [MapboxFollowingFrameProcessor] Start position is beyond line I/stem.br_expres(30124): Explicit concurrent copying GC freed 6239(335KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 8709KB/17MB, paused 146us total 61,031ms

@marciotisouza I got the same status if I do not invoke the finishNavigation() After I invoked the finishNavigation() [*without clearRoute()], it could stop to fire MapBoxEvent.progress_change and show MapBoxEvent.navigation_cancelled

But it will not able to receive the MapBoxEvent.progress_change anymore... So that the ManeuverView becomes blank....

rickylaw-dh commented 9 months ago

[Update] After deep checking the Android side logic in Turn2Turn.kt I know the logic and it matches my finding

And, I found a method to let the MapBoxEvent.progress_change fire after I try to startNavigation() again If I put the app background and foreground, it will work fine...

So, I think the final question is, how to trigger the MapBoxEvent.progress_change without background and foreground the app...

rickylaw-dh commented 9 months ago

[Update] When I try to trigger the MapBoxEvent.progress_change without background and foreground the app I hit the troubling issue now...

If I keep the Widget and do not dispose of it, I will get the Surface cache on the top layer... No way to clear it...

Sorry guys... Maybe my approach doesn't work😭

rickylaw-dh commented 9 months ago

[Update] I am facing https://github.com/flutter/flutter/issues/89558 problem now My above method was keeping the widget to avoid the app crashing after starting navigation more the 2 times But it seems cannot be fixed until Flutter releases a new framework...

Someone says that add the below lines into the MainActivity.kt can fix `
override fun onCreate(savedInstanceState: Bundle?) { intent.putExtra("background_mode", "transparent"); super.onCreate(savedInstanceState); }

override fun onFlutterTextureViewCreated(flutterTextureView: FlutterTextureView) { // We do not actually need a transparent TextureView. flutterTextureView.isOpaque = true; super.onFlutterTextureViewCreated(flutterTextureView); } `

But I cannot run the app after add the code

eopeter commented 9 months ago

Did the work around not work?

https://github.com/flutter/flutter/issues/89558#issuecomment-1446194172

rickylaw-dh commented 9 months ago

I don't know why no error prompt after the project added the workaround code But I guess it should be related on FlutterFragmentActivity

rickylaw-dh commented 9 months ago

@eopeter I can run the app many times without crashing and no textureview cache on top now...

https://github.com/flutter/flutter/issues/89558#issuecomment-1446194172 It provided some methods for us to add to the MainActivity.kt, but it is not been fully suitable for this library...

It should have 2 problems for me

  1. I forgot to import the necessary classes after I added these methods... (e.g.: Bundle, TextureView)
    import android.os.Bundle
    import io.flutter.embedding.android.FlutterTextureView
  2. The onFlutterTextureViewCreated is only for FlutterActivity or FlutterFragment. (I search it on https://api.flutter.dev/javadoc/index.html#)

Since the library is required to use FlutterFragmentActivity, so I only add

    override fun onCreate(savedInstanceState: Bundle?) {
        getIntent().putExtra("background_mode", "transparent");
        super.onCreate(savedInstanceState);
    }

And now, I have new issue πŸ˜‚ https://github.com/note11g/flutter_naver_map/issues/56 Blank Screen after add the putExtra("background_mode", "transparent");

eopeter commented 9 months ago

Are you able to do a PR to apply the solution? If not, I can look more closely at what you did and see if I can incorporate it

eopeter commented 9 months ago

We can set the background mode to transparent via styles it think

rickylaw-dh commented 9 months ago

I did not edit anything of the library.

The workaround to handle this issue should be how to config my Flutter app project and change the implementation of the embedded view in my app widget.

(The custom MapBoxNavigationViewController & MapBoxNavigationView part mainly is for adding a log to debug.)

rickylaw-dh commented 9 months ago

Oh yeah... The blank screen solved

Following the comment https://github.com/note11g/flutter_naver_map/issues/56#issuecomment-1549028306

I go to https://github.com/jonbhanson/flutter_native_splash/issues/54 And edit my AndroidManifest.xml and style.xml

Then the blank screen gone...

rickylaw-dh commented 9 months ago

Hmmm, I guess it should be my final update on this issue.

Some of us may use SafeArea with top: true to contain the embedded view

It may have a little bit of embedded view shown on the Android notification bar area if we do not set the notification bar color after the "hybrid component cached to show on the screen top layer issue"

My workaround is updating the main.dart

Future<void> main() async {
   SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
     systemNavigationBarColor: Colors.blue, // navigation bar color
     statusBarColor: Colors.pink, // status bar color
   ));
   await startup('environments/dev.env');
}

Sorry, @eopeter I know this part is not related to your library, I just wanna have a full workaround for others πŸ™πŸ»

eopeter commented 9 months ago

Thanks for digging into this. Would definitely like a solution that others can refer to when they encounter this issue.

reubendeekay commented 9 months ago

@rickylaw-dh Could you do a detailed update as one comment on how you were able to solve this issue? It will really help alot of people. Also if you changed anything on the library you can do a PR. @eopeter Have you had time to look into this issue? I think it has the largest engagement and request

rickylaw-dh commented 9 months ago

I would not solve it. I just based on the behavior and applied some workaround to my project

The library is good and the main issue is it will crashes when trying to start navigation more than 3 times in embedded view

if keeps to create and destroy the widget,

if keeps the widget with GlobalKey and no create and destroy


My step,

  1. I wrapped a custom widget to use the embedded view

  2. Use GlobalKey to try to keep my custom widget instance at my main page Any Visibility or children array with if () ... {} which is wrapped to contain my custom widget will count in this case... Resize the custom widget to zero / lose constraint will not crash

  3. Try to re-structure my main page to let the custom widget keep on the app session and only resize it if needed to present

  4. Use GlobalKey to get currentState control of the custom widget methods (The methods invoke the map "start route then start navigation" AND "stop navigation") ** Stop navigation is okay, I do not clear route

  5. MainActivty.kt add onCreate()

    override fun onCreate(savedInstanceState: Bundle?) {
        getIntent().putExtra("background_mode", "transparent");
        super.onCreate(savedInstanceState);
    }
  6. Update the style.xml and AndroidManifest.xml to handle blank screen issue (https://github.com/jonbhanson/flutter_native_splash/issues/54)

  7. Avoid the Android notification bar to show the map, then apply color to cover it

    Future<void> main() async {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
     systemNavigationBarColor: Colors.blue, // navigation bar color
     statusBarColor: Colors.pink, // status bar color
    ));
    await startup();
    }

@reubendeekay I hope this can help you.

reubendeekay commented 9 months ago

@rickylaw-dh Thank you for diving deep and trying to help. Can you please send me a code snippet of the main file and the navigation file to better see your workaround. I will really appreciate it

reubendeekay commented 9 months ago

@eopeter Please take a look into this issue related to null required view/view binding

reubendeekay commented 8 months ago

@eopeter Any update?

marcoberetta96 commented 8 months ago

is there any update on this?

reubendeekay commented 7 months ago

@eopeter Any update?

reubendeekay commented 7 months ago

Hello @eopeter

eopeter commented 7 months ago

Hello, I do not have any update on this

skaterschikov commented 5 months ago

Hi everyone, I've tried several approaches, but the only way to make it work is by keeping the navigation widget with a global key and never allowing it to be disposed. You can place it at the bottom of the stack when it shouldn't be visible.

rickylaw-dh commented 5 months ago

Then another issue may occur...

The widget can keeps without crash app, but it could not start navigation normally until the app being to background and then come back to foreground.

(I still cannot handle this issue...

Shaddynotshady commented 3 months ago

is there any solution found?

skaterschikov commented 3 months ago

is there any solution found?

Yes, just avoid using the drop-in UI and manually use the core components by following the Mapbox Examples available at https://github.com/mapbox/mapbox-navigation-android-examples. I have completely rewritten this plugin to meet my company's needs

reubendeekay commented 3 months ago

is there any solution found?

Yes, just avoid using the drop-in UI and manually use the core components by following the Mapbox Examples available at https://github.com/mapbox/mapbox-navigation-android-examples. I have completely rewritten this plugin to meet my company's needs

Could you please strip off sensitive information for your company and provide us a skeleton of this code. This would go a long way into helping hundreds of people.

reubendeekay commented 2 months ago

@skaterschikov please reach out to me on mrreubenyt@gmail.com