Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force quit on consecutive geometry tasks (com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup) #2493

Closed
sufyanAbbasi opened this issue Jun 11, 2024 · 2 comments · Fixed by #2588
Assignees
Labels
type: bug Something isn't working

Comments

@sufyanAbbasi
Copy link
Contributor

Describe the bug

Received the following error when two subsequent location tasks are being rendered: the map doesn't render and we see this in the stack trace:

java.lang.ClassCastException: com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup
  at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:537)
  at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272)
  at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
  at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1839)
  at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1782)
  at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:565)
  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:8177)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

I placed breakpoints at the exact line where the crash occurs and inspected the thing that was failing to cast as a ViewGroup. It turns out that the crash happens when it tries to render the compass of all things!

It happens specifically when I try to render the DrawAreaTaskFragment before or after a drop pin LOI task.

When I just have a Draw Area LOI task and no other, then it seems to work

To Reproduce
Steps to reproduce the behavior:

  1. Publish a survey with the default capture location task and then an ad-hoc LOI task (e.g. capture location again).
  2. Zoom in and start a job, then see that the first task, the default capture task, is broken with a white screen.

Expected behavior

  1. The map is rendered.
@sufyanAbbasi sufyanAbbasi added the type: bug Something isn't working label Jun 11, 2024
@sufyanAbbasi
Copy link
Contributor Author

This is unfortunately blocking the end to end tests as well as exasperated by the fact that we always have a capture location task as the first task by default, since ad-hoc surveys will always put the loiTask afterwards

@sufyanAbbasi sufyanAbbasi self-assigned this Jul 24, 2024
@gino-m gino-m changed the title Consecutive geometry tasks fails to render (com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup) Force quite on consecutive geometry tasks (com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup) Jul 29, 2024
@gino-m gino-m changed the title Force quite on consecutive geometry tasks (com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup) Force quit on consecutive geometry tasks (com.google.maps.api.android.lib6.impl.as cannot be cast to android.view.ViewGroup) Jul 29, 2024
@sufyanAbbasi
Copy link
Contributor Author

Ok, I found the problem, it is so silly...

val rowLayout = LinearLayout(requireContext()).apply { id = View.generateViewId() }

Here we create a RowLayout with a generated ID that is usually 0x5, that is, it returns the next ID that has not been assigned. However, when we go to render it here, the GoogleMapsFragment is also rendered on the page, so when we try to look for the container by ID, there is a Compass element on the GoogleMaps which also has ID 0x5, so at render time, it finds the Compass element, i.e., com.google.maps.api.android.lib6.impl.as, from the GoogleMapsFragment instead of the newly created RowLayout!

.add(rowLayout.id, DropPinTaskMapFragment.newInstance(viewModel, map), "Drop a pin fragment")

When I arbitrarily added 10,000 to the ID, the crash is prevented, hence I believe this is an ID conflict problem.

The fix is to fuzz the ID numbers to decrease the chance of collisions, or somehow get it to always find the RowLayout element every time, maybe there's a different add we could do? Not really sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Projects
Status: Done
2 participants