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

Crash - Failed to load dynamic library 'librive_text.so' #403

Open
daniel102102 opened this issue Jun 23, 2024 · 12 comments
Open

Crash - Failed to load dynamic library 'librive_text.so' #403

daniel102102 opened this issue Jun 23, 2024 · 12 comments
Labels
bug Something isn't working

Comments

@daniel102102
Copy link

daniel102102 commented Jun 23, 2024

Hi. We are using rive for flutter.

We see a massive crash in firabse on Android 5 and Android 6, see callstack below. It happens on various devices.
librive_text.so is included in compilation for all architectures.

      Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Invalid argument(s): Failed to load dynamic library 'librive_text.so': dlopen failed: library "librive_text.so" not found
   at new DynamicLibrary.open(dart:ffi)
   at ._loadLibrary(rive_audio_ffi.dart:41)
   at .nativeLib(rive_text_ffi.dart:11)
   at .init(rive_text_ffi.dart)
   at .initFont(rive_text_ffi.dart)
   at Font.initialize(rive_text.dart:477)
   at RiveFile.initialize(rive_file.dart:383)
   at EndScreenAnimation.initializeRive(end_screen_animation.dart:15)
   at TapToZoomTutorialState._loadRiveFile(tap_to_zoom_tutorial.dart:32)
   at TapToZoomTutorialState.initState(tap_to_zoom_tutorial.dart:28)
   at StatefulElement._firstBuild(framework.dart:5618)
   at ComponentElement.mount(framework.dart:5463)
   at Element.inflateWidget(framework.dart:4340)
   at MultiChildRenderObjectElement.inflateWidget(framework.dart:6904)
   at MultiChildRenderObjectElement.mount(framework.dart:6916)
   at Element.inflateWidget(framework.dart:4340)
   at Element.updateChild(framework.dart:3849)
   at ComponentElement.performRebuild(framework.dart:5512)
   at Element.rebuild(framework.dart:5203)
   at ComponentElement._firstBuild(framework.dart:5469)
   at ComponentElement.mount(framework.dart:5463)
   at Element.inflateWidget(framework.dart:4340)
   at Element.updateChild(framework.dart:3849)
   at ComponentElement.performRebuild(framework.dart:5512)
   at Element.rebuild(framework.dart:5203)
   at ComponentElement._firstBuild(framework.dart:5469)
   at ComponentElement.mount(framework.dart:5463)
   at Element.inflateWidget(framework.dart:4340)
   at Element.updateChild(framework.dart:3849)
   at _LayoutBuilderElement._layout.layoutCallback(layout_builder.dart:155)
   at BuildOwner.buildScope(framework.dart:2845)
   at _LayoutBuilderElement._layout(layout_builder.dart:173)
   at RenderObject.invokeLayoutCallback.<fn>(object.dart:2688)
   at PipelineOwner._enableMutationsToDirtySubtrees(object.dart:1097)
   at RenderObject.invokeLayoutCallback(object.dart:2688)
   at RenderConstrainedLayoutBuilder.rebuildIfNecessary(layout_builder.dart:248)
   at _RenderLayoutBuilder.performLayout(layout_builder.dart:331)
   at RenderObject.layout(object.dart:2577)
   at MultiChildLayoutDelegate.layoutChild(custom_layout.dart:173)
   at _ScaffoldLayout.performLayout(scaffold.dart:1097)
   at MultiChildLayoutDelegate._callPerformLayout(custom_layout.dart:237)
   at RenderCustomMultiChildLayoutBox.performLayout(custom_layout.dart:404)
   at RenderObject.layout(object.dart:2577)
   at RenderProxyBoxMixin.performLayout(proxy_box.dart:105)
   at RenderObject.layout(object.dart:2577)
   at RenderProxyBoxMixin.performLayout(proxy_box.dart:105)
   at _RenderCustomClip.performLayout(proxy_box.dart:1426)
   at RenderObject.layout(object.dart:2577)
   at RenderPadding.performLayout(shifted_box.dart:239)
   at RenderObject.layout(object.dart:2577)
   at RenderProxyBoxMixin.performLayout(proxy_box.dart:105)
   at RenderObject._layoutWithoutResize(object.dart:2416)
   at PipelineOwner.flushLayout(object.dart:1051)
   at PipelineOwner.flushLayout(object.dart:1064)
   at RendererBinding.drawFrame(binding.dart:577)
   at WidgetsBinding.drawFrame(binding.dart:1138)
   at RendererBinding._handlePersistentFrameCallback(binding.dart:443)
   at SchedulerBinding._invokeFrameCallback(binding.dart:1392)
   at SchedulerBinding.handleDrawFrame(binding.dart:1313)
   at SchedulerBinding._handleDrawFrame(binding.dart:1171)
@daniel102102 daniel102102 added the bug Something isn't working label Jun 23, 2024
@HayesGordon
Copy link
Contributor

Hi @daniel102102, which version of the Rive-Flutter runtime are you using? And did this recently start after updating?

@kaptnkoala
Copy link

kaptnkoala commented Jun 24, 2024

Hi @HayesGordon, we also see this error occur in our production app after updating the rive dependency from 0.13.1 to 0.13.7 (which bumps the rive_common dependency from 0.3.3 to 0.4.9 under the hood). We did not see any problems regarding the Rive-Flutter runtime before, it recently started to occur after the mentioned update.

Like @daniel102102 mentioned this problem happens to 99% on devices running Android 6.

@HayesGordon
Copy link
Contributor

@kaptnkoala I'd just like to confirm a few things.

  • Does your Rive file contain Rive Text or Rive Audio?

  • Are you specifying a buildType or using the defaults? For example:

buildTypes {
    release {
        // other configs
        ndk {
            abiFilters 'armeabi-v7a','arm64-v8a','x86_64', 'x86'
        }
    }
}
  • Are you passing in any additional flags when building the release APK?

  • You mentioned that you verified that the release APK in production contained the .so files?

  • Which version of Flutter are you using?

One potentially relevant issue I've found is: simolus3/drift#895 (comment)

More info here: simolus3/drift#895 (comment)

We could look into doing something similar (it's a bit of a hack) but I'm unable to verify my side if this will work as I cannot reproduce the issue. Can you reproduce this issue on your end, or are you only seeing this in production?

@daniel102102
Copy link
Author

Hi @HayesGordon. We are using rive: 0.13.8 and rive_common: ^0.4.9. Massive crashes started in last days, after switching to new version. Before crash was avialble but was rare.

@HayesGordon
Copy link
Contributor

Could you please confirm if you're Rive file makes use of Rive Text or Rive Audio. Answering this is important to help me pinpoint the issue.

Could you also answer the other questions if possible.

@kaptnkoala
Copy link

kaptnkoala commented Jun 26, 2024

Hey @HayesGordon, please find the answers to your questions attached.

Does your Rive file contain Rive Text or Rive Audio?

No, in our case the affected rive files are not using Rive Text or Rive Audio?

Are you specifying a buildType or using the defaults? For example:

Yes, we are not building our app for the 'x86' architecture, so our release NDK settings look like this:

    buildTypes {
        release {
            ndk {
                abiFilters 'armeabi-v7a','arm64-v8a','x86_64'
                debugSymbolLevel 'FULL'
            }
        }
    }

Are you passing in any additional flags when building the release APK?

We only pass additional --dart-define Flags when building the release APK?

You mentioned that you verified that the release APK in production contained the .so files?

Yes, i can verify that the generated APK contains the librive_text.so in the 'lib/arm64-v8a', 'lib/armabi-v7a' and 'lib/x86_64' directories.

Which version of Flutter are you using?

We are using Flutter 3.19.6

I am not exactly sure what workaround you are suggesting, because you seemed to have referenced the same issue comment twice. We also do not have Apps at Hand here right now and can reproduce the issue, we only see it as error with high volume in our reporting tools. For the moment we have reverted back to rive 0.13.1, which mitigated the problem for the production app.

@HayesGordon
Copy link
Contributor

Thanks for the info @kaptnkoala. The other link I wanted to send was this: https://github.com/simolus3/sqlite3.dart/tree/main/sqlcipher_flutter_libs#problems-on-android-6

In older versions of Flutter, Android 6 caused issues, old documentation mentions:

If you build an App Bundle Edit android/gradle.properties and add the flag: android.bundle.enableUncompressedNativeLibs=false.

If you build an APK Make sure android/app/src/AndroidManifest.xml doesn’t set android:extractNativeLibs=false in the <application> tag.

But I do not know if that is still relevant.

We can push out the same solution that sqlite3 did. It requires loading the library natively from Kotlin and then accessing it through the data directory.

I'll let you know here once that is out.

@kaptnkoala
Copy link

We have set the flag android.bundle.enableUncompressedNativeLibs=false in the android/gradle.properties and not set the android:extractNativeLibs=false Flag in AndroidManifest.

Has anything changed between version 0.13.1 and 0.13.8 how the livrive_text.so is loaded, that this problem is starting to gain track now and not in the previous version. I am not sure, if this is really the best solution to the problem. I will ping a colleague that is more familiar with the native parts of Flutter. @blaugold What do you think about this?

@HayesGordon
Copy link
Contributor

After version 0.13.1 the requirement to load in these libraries changed. Previously the native libraries were only loaded if a .riv file contained Rive Text. We optimistically checked to see if the .riv file had Rive Text in it - if not we would not initliaze the library.

But since then we've introduced more features, specifically a new layout engine, which requires Rive Flutter to always load + initialize the native library.

That is why you're seeing it now and not before.

On the Rive Android runtime we had similar issues in the past where Android has issues linking these libraries. There exists a package for Android called ReLinker which we use to ensure the libraries are linked on older devices.

This is the first/only report about Rive Flutter not working on older Android devices.

@HayesGordon
Copy link
Contributor

Link to the PR that made the change to require the libraries to always be loaded: a22fc5f

@centy
Copy link

centy commented Jun 26, 2024

Have you tried https://github.com/KeepSafe/ReLinker ?

If your app includes native libraries, and your minimum SDK is below API 23 (Marshmallow), you need ReLinker.

There are a number of different bugs addressed by ReLinker; the last of these was resolved as of Marshmallow. As long as your app's min SDK is at or above it, loading libraries via System.loadLibrary("foo") is safe.

@blaugold
Copy link

blaugold commented Jul 1, 2024

We are using minSdkVersion 23, so we should not need ReLinker.

@kaptnkoala Those workarounds feel a bit hacky, but the only solution for those older Android versions. 🫠

rive-engineering pushed a commit that referenced this issue Jul 8, 2024
Refactors the library loading to reuse the same code across the different FFI modules.

Introduces a workaround for Android library loading, potentially fixing [403](#403)

Diffs=
d5ed4ca9b feat: add applyWorkaroundToRiveOnOldAndroidVersions (#7485)
1e7b1c030 add missing validations (#7532)

Co-authored-by: Gordon <pggordonhayes@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants