birkir / react-native-carplay

CarPlay with React Native
https://birkir.dev/react-native-carplay/
MIT License
625 stars 103 forks source link

Android late init carContext crash #164

Open KestasVenslauskas opened 5 months ago

KestasVenslauskas commented 5 months ago

Describe the bug Just installed this package with all setup mentioned in documentation for android. App crashes when creating the template for example new ListTemplate({...}) Because it already expect carContext to be initialised.

                 kotlin.UninitializedPropertyAccessException: lateinit property carContext has not been initialized
                    at org.birkir.carplay.CarPlayModule.createScreen(CarPlayModule.kt:276)
                    at org.birkir.carplay.CarPlayModule.createTemplate$lambda$0(CarPlayModule.kt:109)
                    at org.birkir.carplay.CarPlayModule.$r8$lambda$KGCg1YkdHhdDVzVWZBIlxyzACWg(Unknown Source:0)
                    at org.birkir.carplay.CarPlayModule$$ExternalSyntheticLambda0.run(Unknown Source:8)
                    at android.os.Handler.handleCallback(Handler.java:958)
                    at android.os.Handler.dispatchMessage(Handler.java:99)
                    at android.os.Looper.loopOnce(Looper.java:205)
                    at android.os.Looper.loop(Looper.java:294)
                    at android.app.ActivityThread.main(ActivityThread.java:8194)
                    at java.lang.reflect.Method.invoke(Native Method)

Expected behavior A clear and concise description of what you expected to happen.

Android Auto (please complete the following information):

Additional context Interesting that when I call CarPlay.registerOnConnect(onConnectHandler); I do get callback called instantly. I just ran the app in a emulator that should not have any android auto or automotive connection yet.

UPDATE: Just tried connecting to android auto HUD before launching the app - same result

KestasVenslauskas commented 5 months ago

So I managed to connect to android auto DHU. And looks like list template works. But still wonder why we need to registerRunnable 'AndroidAuto' ? What is the expected flow here? Shoul I register empty 'AndroidAuto' runnable (or with connection events), but I control the templates from main component? Or do I implement Android auto navigation & templating on 'AndroidAuto' runnable and send events to it from main component?

The main problem remains that even I dont have running AndroidAuto DHU it still fires didConnect events. After I try to do anything with it it crashes with late init exception for carContext. The root cause of it is in CarPlayModule.kt >> checkForConnection. It's called from CarPlay.js in CarPlayInterface constructor()

BohdanSol commented 5 months ago

Hey @KestasVenslauskas and community! After some research on the issue (faced as well and thats how I found this thread) I think I've found a solution, at least a way to unblock me, you and others from getting that issue.

So for CarPlayModule.kt I manually changed:

  @ReactMethod
  fun toast(text: String, duration: Int) {
    CarToast.makeText(carContext, text, duration).show()
  }

to:

  @ReactMethod
  fun toast(text: String, duration: Int) {
    if (!::carContext.isInitialized) {
      Log.e(TAG, "carContext is not initialized. Cannot show toast.")
      return
    }
    CarToast.makeText(carContext, text, duration).show()
  }

And then at the beginning of createScreen fun I added one if statement:

private fun createScreen(templateId: String): CarScreen? {
    if (!::carContext.isInitialized) {
        Log.e(TAG, "carContext not initialized")
        return null
    }
    // The rest of method...
}

I'm not entirely certain what resolved the issue, but following my adjustments, the List template started functioning, the app no longer crashes, and I'm now delving deeper into the library's capabilities!