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

fix: native library loading #355

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

fix: native library loading #355

wants to merge 1 commit into from

Conversation

DatL4g
Copy link

@DatL4g DatL4g commented Feb 15, 2025

Introduce a NativeLoader which takes care of loading native libraries. ReLinker is not needed on API Level > 23 and causes more trouble than it solves.

Refs: #341

Introduce a NativeLoader which takes care of loading native libraries.
ReLinker is not needed on API Level > 23 and causes more trouble than it solves.

Refs: rive-app#341
@ernestoyaquello
Copy link

Does this fix #341, or is it just related to it? I am not entirely sure what's going on here. 😅

@DatL4g
Copy link
Author

DatL4g commented Feb 17, 2025

@ernestoyaquello It's related to the mentioned issue since it's a known bug in ReLinker for years.
It will probably fix the issue as well, at least I don't see any reason why it should not work after merging.
I also use this kind of method in production apps and works without crashes, no matter if real/emulator or architecture.

More Context

Rive uses ReLinker to load native code which is only needed on older Android API Levels (below 23, Android Marshmallow).
It uses it's own native code loading process instead of System.loadLibrary because older phones did not support this properly.

Starting with Android 23 and up the System.loadLibrary works without issues.

Code Explanation

The updated and introduced code checks if the phone is old, then it uses ReLinker, otherwise it uses the normal System.loadLibrary method.
Additionally it won't crash the application if Rive could not be initialized, the Rive.init method returns a Boolean whether it could be loaded.
This way people can dynamically disable animations, only thing to mention is that it will always return false if it's called more than once.

Work Around while not merged

I use this code to initialize rive properly:
Btw I am using a more complex version of NativeLoader here which is not required for rive.

/**
 * Retrieves the rive native binary name using reflection, falls back to "rive-android"
 * Uses NativeLoader to load the native binary
 * Sets the default renderer using reflection
 */
fun Rive.initSafely(
    context: Context,
    defaultRenderer: RendererType = defaultRendererType
) {
    val riveClass = "app.rive.runtime.kotlin.core.Rive"
    val libName = runCatching {
        val clazz = Class.forName(riveClass)
        val field = clazz.getDeclaredField("RIVE_ANDROID")
        field.isAccessible = true
        field.get(null) as? String
    }.getOrNull()?.trim()?.ifBlank { null } ?: "rive-android"

    val libLoaded = NativeLoader.loadLibrary(context, libName)
    val rendererSet = this.defaultRendererType == defaultRenderer || runCatching {
        val clazz = Class.forName(riveClass)
        val field = clazz.getDeclaredField("defaultRendererType")
        field.isAccessible = true
        field.set(clazz, defaultRenderer)
    }.isSuccess

    if (libLoaded && rendererSet) {
        initializeCppEnvironment()
    } else {
        init(context, defaultRenderer)
    }
}

@umberto-sonnino
Copy link
Contributor

HI @DatL4g, thanks for your contribution!

It looks very promising and we're keen to find a way to resolve #341 for all those who reported it. As I mentioned in the issue thread, before integrating this PR, we'd like to test this and make sure this is solving the crashes.

Could you give us more specific repro steps? Which specific devices/ABIs have you confirmed experience the crash with the current implementation?

Once we validate this, we're happy to merge it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants