rive-app/rive-android

'Has no surface' when using Rive in Compose

PhilippNowak96 opened this issue · 6 comments

Description

When using Rive as part of an AndroidView in Compose we currently experience log spam of

2022-12-16 13:56:22.630 2490-3218/xxx E/src/models/jni_renderer_skia.cpp:163: Has No Surface!

until we leave the screen containing the animation. Beside possible performance issues, which we are not aware of right now, there are no other issues. Animations work as expected.

Provide a Repro

The following code snippet should reproduce the issue:

@Composable
fun CustomRiveAnimationView(
    modifier: Modifier = Modifier,
    @RawRes animation: Int,
    stateMachineName: String? = null,
    alignment: Alignment = Alignment.CENTER
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            RiveAnimationView(context).also {
                it.setRiveResource(
                    resId = animation,
                    stateMachineName = stateMachineName,
                    alignment = alignment
                )
            }
        }
    )
}

Expected behavior

Log isn't spammed -> no error occurs

Device & Versions (please complete the following information)

  • Device: Any
  • SDK Level: Tested on API 33 and API 31
  • Rive-Android: 4.2.1

Is it solved?

No it isn't. We also experienced that it only happens when the RiveAnimationView is currently not in the visible region (e.g. scrolled away etc.)

The same error message appears when I use it on a ViewPager item. Especially when I step back to a previous item.

Hi @PhilippNowak96!
I tried copy-pasting your snippet into the basic Empty Compose Activity generated via Android Studio and it's currently behaving as expected with the riv files available in the example like so:

class ComposeActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            // A surface container using the 'background' color from the theme
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                CustomRiveAnimationView(animation = R.raw.basketball)
            }
        }
    }
}

Since your report is from 4.2.1 and we're currently at 4.3.2, would you mind trying it on the latest version? One of our latest patches might've fixed this

Hi @umberto-sonnino,
thanks for looking into this!

At first: I guess my initial post missed a detail which the later comments included already: You need to get the RiveAnimationView outside of the displayed content. That wasn't clear to me when I initially created the post and somehow seemed to be the case when I created and tested the repro snippet. Sorry for that!

So the actual repro for example using the Accompanist HorizontalPager could look like this:

class MainActivity : ComponentActivity() {
    @OptIn(ExperimentalPagerApi::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            RiveAndroidCrashTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    HorizontalPager(count = 3) {
                        if (it == 0) {
                            CustomRiveAnimationView(
                                animation = R.raw.survey,
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .requiredHeight(200.dp)
                            )
                        } else {
                            Text("Page: $it")
                        }
                    }
                }
            }
        }
    }

    @Composable
    fun CustomRiveAnimationView(
        modifier: Modifier = Modifier,
        @RawRes animation: Int,
        stateMachineName: String? = null,
        alignment: Alignment = Alignment.CENTER,
    ) {
        AndroidView(
            modifier = modifier,
            factory = { context ->
                RiveAnimationView(context).also {
                    it.setRiveResource(
                        resId = animation,
                        stateMachineName = stateMachineName,
                        alignment = alignment,
                    )
                }
            }
        )
    }
}

But as you mentioned this repro was for 4.2.1. After verifying the repro still works a couple of minutes ago I upgraded to 4.3.2 and the Has No Surface! message is gone, even if you scroll to the other pages not containing the RiveAnimation. So I guess this was fixed and can be closed 😊

Great to hear, going to close it then!