Drjacky / ImagePicker

📸Image Picker for Android, Pick images from Gallery or Capture a new image with Camera🖼
https://github.com/Drjacky/ImagePicker
Apache License 2.0
230 stars 57 forks source link

Getting ANR in some devices when picking from Gallery. #104

Open EzequielAdrianM opened 11 months ago

EzequielAdrianM commented 11 months ago

Since we implemented this library as a Ucrop replacement, it is working flawlessly and it has all the modern characteristics we need. Unfortunately, our ANR rate started to increase significantly after introducing this library.

Here is the stack trace we got:

main (native):tid=1 systid=8932 
#00 pc 0xd66c4 libc.so (__ioctl + 4)
#01 pc 0x934a0 libc.so (ioctl + 156)
#02 pc 0x519e4 libbinder.so (android::IPCThreadState::talkWithDriver(bool) + 296)
#03 pc 0x529e0 libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*) + 60)
#04 pc 0x52750 libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 184)
#05 pc 0x4b014 libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 152)
#06 pc 0x125a68 libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int) + 152)
       at android.os.BinderProxy.transactNative(Native method)
       at android.os.BinderProxy.transact(BinderProxy.java:540)
       at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:779)
       at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1983)
       at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1921)
       at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder(ImageDecoder.java:274)
       at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1862)
       at com.github.drjacky.imagepicker.provider.CropProvider.getBitmap(CropProvider.kt:219)
       at com.github.drjacky.imagepicker.provider.CropProvider.cropImage(CropProvider.kt:159)
       at com.github.drjacky.imagepicker.provider.CropProvider.startIntent(CropProvider.kt:128)
       at com.github.drjacky.imagepicker.ImagePickerActivity.setImage(ImagePickerActivity.kt:164)
       at com.github.drjacky.imagepicker.provider.GalleryProvider.handleResult(GalleryProvider.java:186)
       at com.github.drjacky.imagepicker.provider.GalleryProvider.handleResult(GalleryProvider.java:154)
       at com.github.drjacky.imagepicker.ImagePickerActivity.galleryLauncher$lambda$0(ImagePickerActivity.java:55)
       at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:149)
       at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
       at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
       at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
       at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
       at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
       at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:68)
       at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted(ReportFragment.java:187)
       at android.app.Activity.dispatchActivityPostStarted(Activity.java:1420)
       at android.app.Activity.performStart(Activity.java:8177)
       at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3553)
       at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
       at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2151)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:250)
       at android.app.ActivityThread.main(ActivityThread.java:7844)
       at java.lang.reflect.Method.invoke(Native method)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)

And this is the current implementation code:

String[] allowedMime = new String[] {"image/jpeg", "image/jpg", "image/webp"};
ImagePicker.with(TakePicActivity2.this).provider(ImageProvider.GALLERY).galleryMimeTypes(allowedMime).setMultipleAllowed(false).crop(9, 16).maxResultSize(720, 1920, true).setOutputFormat(Bitmap.CompressFormat.JPEG).createIntent()

We think this happens due to the user picking some very large pictures from the gallery. I didn't check the library code, but maybe there are some bitmap processing operations that should be done outside the UI thread... Maybe it might be convenient to not even list those galley pictures bigger than certain resolution.