koral-- / android-gif-drawable

Views and Drawable for displaying animated GIFs on Android
Other
9.54k stars 1.78k forks source link

Could not find 'libpl_droidsonroids_gif.so'. Looked for: [arm64-v8a, armeabi-v7a, armeabi], but only found: []. #778

Closed sstanislavsky closed 2 years ago

sstanislavsky commented 2 years ago

version of lib - 1.2.23 target sdk - 30

There are several crash reports from Firebase Crashlytics. I use a app bundle. Didn't find a solution here and on google. Can't reproduce it locally. I will be glad for any help

Caused by pl.droidsonroids.relinker.MissingLibraryException: Could not find 'libpl_droidsonroids_gif.so'. Looked for: [arm64-v8a, armeabi-v7a, armeabi], but only found: [].
       at pl.droidsonroids.relinker.ApkLibraryInstaller.installLibrary(ApkLibraryInstaller.java:173)
       at pl.droidsonroids.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:180)
       at pl.droidsonroids.relinker.ReLinkerInstance.loadLibrary(ReLinkerInstance.java:136)
       at pl.droidsonroids.relinker.ReLinker.loadLibrary(ReLinker.java:70)
       at pl.droidsonroids.relinker.ReLinker.loadLibrary(ReLinker.java:51)
       at pl.droidsonroids.gif.LibraryLoader.loadLibrary(LibraryLoader.java:52)
       at pl.droidsonroids.gif.GifInfoHandle.<clinit>(GifInfoHandle.java:27)
       at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:161)
       at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:96)
       at pl.droidsonroids.gif.GifViewUtils.setResource(GifViewUtils.java:55)
       at pl.droidsonroids.gif.GifViewUtils$GifImageViewAttributes.getResourceId(GifViewUtils.java:138)
       at pl.droidsonroids.gif.GifViewUtils$GifImageViewAttributes.<init>(GifViewUtils.java:124)
       at pl.droidsonroids.gif.GifViewUtils.initImageView(GifViewUtils.java:29)
       at pl.droidsonroids.gif.GifImageView.<init>(GifImageView.java:41)
       at java.lang.reflect.Constructor.newInstance0(Constructor.java)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
       at android.view.LayoutInflater.createView(LayoutInflater.java:864)
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1016)
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:971)
       at android.view.LayoutInflater.rInflate(LayoutInflater.java:1133)
       at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1094)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:692)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:536)
       at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:126)
       at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)
       at com.klikatech.rollo.ui.base.databinding.DataBindingFragment.setupViewBinding(DataBindingFragment.java:39)
       at com.klikatech.rollo.ui.base.databinding.DataBindingFragment.onCreateView(DataBindingFragment.java:28)
       at com.klikatech.rollo.ui.base.screen.ScreenFragment.onCreateView(ScreenFragment.java:52)
       at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
       at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
       at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
       at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2106)
       at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
       at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524)
       at android.os.Handler.handleCallback(Handler.java:888)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:213)
       at android.app.ActivityThread.main(ActivityThread.java:8147)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

Devices

Screenshot 2021-11-02 at 16 29 57 Screenshot 2021-11-02 at 16 29 44

Thanks in advance

ljz-ah commented 2 years ago

@sstanislavsky hi , you check the build.gardle in app , the ndk config may be like this : ndk { abiFilters "armeabi" } this config make the apk file generate only armeabi directory ,no have others ,when the app running, wile get this Exception

sstanislavsky commented 2 years ago

Inside my current bundle I can see this lib for different CPU's

Screenshot 2021-11-04 at 12 15 08

I can start my app on emulator x86_64 if I put it abiFilters "armeabi" I can't do it. And I know that - abiFilter will force your APK to package armeabi only and this ABI will become the primary ABI selection for all your devices. In other words, no matter your device is arm64-v8a or armeabi-v7a, the APK manager will pick up the native libs from <your-apk-path>/lib/armeabi/....

As a result it doesn't help me and adds new restrictions. Could you describe how it can help me? Thanks in advance

koral-- commented 2 years ago

Do you have extractNativeLibs set in manifest?

sstanislavsky commented 2 years ago

No, I don't setup android:extractNativeLibs Do you prefer to set this flag to false? How it can help?

from google manual

Whether or not the package installer extracts native libraries from the APK to the filesystem. If set to "false", then your native libraries must be page aligned and stored uncompressed in the APK. Although your APK might be larger, your application should load faster because the libraries are directly loaded from the APK at runtime. On the other hand, if set to "true", native libraries in the APK can be compressed. During installation, the installer decompresses the libraries, and the linker loads the decompressed libraries at runtime; in this case, the APK would be smaller, but installation time might be slightly longer.``Whether or not the package installer extracts native libraries from the APK to the filesystem. If set to "false", then your native libraries must be page aligned and stored uncompressed in the APK. Although your APK might be larger, your application should load faster because the libraries are directly loaded from the APK at runtime. On the other hand, if set to "true", native libraries in the APK can be compressed. During installation, the installer decompresses the libraries, and the linker loads the decompressed libraries at runtime; in this case, the APK would be smaller, but installation time might be slightly longer.

koral-- commented 2 years ago

You may encounter an issue like: https://issuetracker.google.com/issues/147096055 or https://issuetracker.google.com/issues/127691101

On some devices is some cases the native library loading via System.loadLibrary fails. For devices running on Android 6 and newer and AAB you can set android.bundle.enableUncompressedNativeLibs = false Gradle property as a workaround. See https://developer.android.com/studio/releases/gradle-plugin and linked issues for more info about that.

sstanislavsky commented 2 years ago

OK, I will include this line to new release and will text about a result. Thanks

koral-- commented 2 years ago

Closing this issue as not an issue with this library.

chinalwb commented 2 years ago

@sstanislavsky I am facing exactly the same issues, we also submit .aab to Play Store, we can neither reproduce locally. We use 1.2.23 of this lib. I am wondering whether the android:extractNativeLibs="false" in manifest works well for you? Thanks!

BTW, inspired by Koral's comment, I read that post in SO, it says:

When building an AAB, it has the extractNativeLibs flag set to "false" by default. However, as Google Play applies compression on top of the APKs delivered to the end device, this doesn't affect the download size. It means that this flag brings only benefits in case of Android App Bundles - faster installation, less size on disk at almost no additional cost because of no pressure towards the max size limit.

I did build/submit AAB to Play Store. So that means it sets extractNativeLibs flag set to "false" by default even I didn't set it explicitly. It still happens from time to time, not always not on a specific device..

Any idea will be appreciated, thank you!

terencehonles commented 2 years ago

@chinalwb I'm looking into this issue myself, and when reading up on it it seems like bundletool will override whatever you have set in the manifest and you'll need to use the option android.bundle.enableUncompressedNativeLibs=false in your gradle properties to disable that behavior.

I confirmed that the APK generated and downloaded via the Play Store does indeed have android:extractNativeLibs="false" set in the manifest, and while we don't set that in the manifest ourselves I am inclined to understand that it doesn't matter if I set that property since it will be overridden by bundletool.

I'll be enabling the property and calling it a day :wink:

terencehonles commented 2 years ago

@koral-- is there reason that you know of why this needs the .so file to be uncompressed and can't read it from the APK itself? It seems like the aab format leverages this optimization to save disk space and the flag is binary so setting this property would not allow extracting only specific libraries that do not support reading them from the APK file.

koral-- commented 2 years ago

From what I understand from the linked tickets on Google Issue tracker, on some devices extracting .so files is broken. Eg. https://issuetracker.google.com/issues/147096055#comment3

The issue is not in the path where the devices search for the native library: the path of the library in the APK (arm64-v8a) and where it's extracted on the device (arm64) doesn't have to be the same. Those devices seem to have a bug when it comes to reading native libraries when they're not extracted from the APK which is possible since Android M (6.0) when the native libraries are left uncompressed in the APK, which is one of the features that the Android App Bundle takes advantage of to save space on users' devices. If app developers want to get rid of this exception, they can disable this optimization by setting the Gradle property "android.bundle.enableUncompressedNativeLibs=false", at the cost of a bigger size of their app on users' devices and also possibly a larger download size.

terencehonles commented 2 years ago

@koral-- I see, I'm slightly surprised that the relinker isn't able to find the library since what I'm understanding is that the APK would still have it in a specific place (the device isn't modifying the APK when downloading it, right?) and the issue would be where the native libraries look in the uncompressed path(s) and the APK, but I would slightly expect the relinker would be able to extract it to where it needs to go or do I misunderstand what relinker is doing?

koral-- commented 2 years ago

ReLinker was designed to work around issues on API levels < 23 https://github.com/KeepSafe/ReLinker#who-needs-relinker. So, it may not support the mechanisms introduced in the newer API levels.

zhangwenxiang26 commented 1 year ago

I encountered the same problem in OPPO PDKM00 Android 12.

Even if I do the following: android:extractNativeLibs="true" android.bundle.enableUncompressedNativeLibs = false

Is this a problem with the phone model or the App Bundle?

SerialSensor commented 1 year ago

Same Here. Tried all different configs over several releases. Still saw these crashes occasionally.

lambu93 commented 1 year ago

How to solve this problem, I imported this library in the demo and it can run, but this error is reported when I import it in my own project.

koral-- commented 1 year ago

Please create a separate issue with the minimal reproducible sample project.