ModelViewer + SurfaceView within a RecyclerView crash
- Dominant language
- C++
- Stars
- 20.5k
- Forks
- 2.3k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 83
Description
**Describe the bug**
When attaching a `SurfaceView` to a `ModelViewer` within a `RecyclerView`, the view lifecycle isn't properly handled. A `SurfaceView` is detached from the window but not destroyed. When the `SurfaceHolder.Callback` attached within the `UiHelper` callbacks are invoked, the engine has been already been destroyed resulting in the provided stack trace.
**To Reproduce**
Steps to reproduce the behavior:
1. Put multiple `SurfaceView` backed by `ModelViewer` into a `RecyclerView`
2. Scroll up or down until a view is detached from the window, but not destroyed, then scroll back to that view
**Expected behavior**
Any cleanup/configuration (specifically with the engine) should be properly cleaned up/recreated when the view detaches/reattaches itself without relying on complete destruction/reconstruction of the view itself.
**Logs**
```
java.lang.IllegalStateException: Calling method on destroyed Engine
at com.google.android.filament.Engine.getNativeObject(Engine.java:649)
at com.google.android.filament.Engine.createSwapChain(Engine.java:293)
at com.google.android.filament.Engine.createSwapChain(Engine.java:271)
at com.google.android.filament.utils.ModelViewer$SurfaceCallback.onNativeWindowChanged(ModelViewer.kt:362)
at com.google.android.filament.android.UiHelper.createSwapChain(UiHelper.java:570)
at com.google.android.filament.android.UiHelper.access$100(UiHelper.java:120)
at com.google.android.filament.android.UiHelper$1.surfaceCreated(UiHelper.java:405)
at android.view.SurfaceView.updateSurface(SurfaceView.java:1173)
at android.view.SurfaceView.lambda$new$0$SurfaceView(SurfaceView.java:173)
at android.view.-$$Lambda$SurfaceView$w68OV7dB_zKVNsA-r0IrAUtyWas.onPreDraw(Unknown Source:2)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1093)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3096)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1959)
```
**Smartphone (please complete the following information):**
- Device: Sony Xperia 5ii
- OS: Android 11
**Additional context**
Right now it seems the only solution around this (while still using `ModelViewer`) is to force the `RecyclerView` to not recycle those views.
This is possible via
```
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setIsRecyclable(false)
}
```
Contributor guide
Assessment
This issue has not been assessed yet.