apps-android-commons icon indicating copy to clipboard operation
apps-android-commons copied to clipboard

Crash: Application crashes on uploading a large image

Open animeshk08 opened this issue 5 years ago • 43 comments

Summary:

The application crashes on uploading a very large image. In this case, the image size was 28.69MB.

Steps to reproduce:

  1. Find an image which has a large size.
  2. Try uploading it.

System logs:

java.lang.RuntimeException: Canvas: trying to draw too large(192000000bytes) bitmap.
        2020-02-02 05:35:10.603 30429-30429/fr.free.nrw.commons.beta E/AndroidRuntime: FATAL EXCEPTION: main
    Process: fr.free.nrw.commons.beta, PID: 30429
    java.lang.RuntimeException: Canvas: trying to draw too large(192000000bytes) bitmap.
        at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)
        at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:98)
        at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
        at android.widget.ImageView.onDraw(ImageView.java:1360)
        at android.view.View.draw(View.java:20238)
        at android.view.View.updateDisplayListIfDirty(View.java:19113)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.draw(View.java:20241)
        at androidx.viewpager.widget.ViewPager.draw(ViewPager.java:2426)
        at android.view.View.updateDisplayListIfDirty(View.java:19113)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.updateDisplayListIfDirty(View.java:19104)
        at android.view.View.draw(View.java:19966)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
        at android.view.View.draw(View.java:20241)
        at com.android.internal.policy.DecorView.draw(DecorView.java:784)
        at android.view.View.updateDisplayListIfDirty(View.java:19113)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:801)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:3403)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3193)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2562)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1532)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7406)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1092)
        at android.view.Choreographer.doCallbacks(Choreographer.java:888)
        at android.view.Choreographer.doFrame(Choreographer.java:819)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1078)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6823)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)


Device and Android version:

What make and model device: Redmi Note 7 Pro What Android version: Android 9

Commons app version: version: 2.12.2-debug branch: master

Would you like to work on the issue?

Yes. I would like to work on this issue.

animeshk08 avatar Feb 02 '20 00:02 animeshk08

Can I work on this issue ?@maskaravivek, @ashishkumar0207

animeshk08 avatar Feb 02 '20 00:02 animeshk08

I think we can implement image compression before uploading them, however i doubt it's a good idea from user experience standpoint. I mean the standard carrier networks may take a while to upload such a big file, we can prompt users to select file less than , say 20MB

kbhardwaj123 avatar Feb 02 '20 05:02 kbhardwaj123

@kbhardwaj123 One possible solution could be to display a compressed version on the UI and upload the original version

ashishkumar468 avatar Feb 02 '20 05:02 ashishkumar468

@ashishkumar468 yeah that seems appropriate, we can show a compressed one after the file is picked form the gallery or camera intent, so we need to fix this upload issue if we are about to upload the original one

kbhardwaj123 avatar Feb 02 '20 05:02 kbhardwaj123

Tagging @maskaravivek & @nicolas-raoul @misaochan for their inputs.

ashishkumar468 avatar Feb 02 '20 05:02 ashishkumar468

Sir, I think we should allow the users to upload such high resolution images, as the picture I was trying to upload was also taken from the phone camera. Also, the error exists when we try to inflate the image in the background after it has been retrieved from the media storage. So I think even in other sections like explore and contributions we will get the same error when we will click on the image to view it.

One good solution will be to create a utils file(which resizes the image) to handle this error and using it everywhere where we are trying to inflate the image.

animeshk08 avatar Feb 02 '20 08:02 animeshk08

Any updates on this, Sir? @maskaravivek @nicolas-raoul @misaochan

animeshk08 avatar Feb 04 '20 13:02 animeshk08

Going to tag @nicolas-raoul for this one, as I am not sure what the Commons community's stance is on extremely large uploads - it will affect whether we choose to compress before or after.

misaochan avatar Feb 04 '20 17:02 misaochan

Sir any updates on this? @nicolas-raoul

animeshk08 avatar Feb 07 '20 07:02 animeshk08

I think we should support any size that Commons allows us to upload. As the Redmi has 48 megapixels it may hold a lot of details that could be lost if we compressed the image before sending it.

nicolas-raoul avatar Mar 21 '20 12:03 nicolas-raoul

This is not an issue of "uploading" we just tried to show the image in an imageview without decoding it into the bounds of the view. Seeing as how the log mentions at android.widget.ImageView.onDraw(ImageView.java:1360) I would assume using a DraweeView would fix this.

Where in the upload process fails? Is it trying to show it in UploadMediaDetailsFragment where you add title/description?

If anyone can add a large image to this issue for ease of reproduction that will help whoever takes up this ticket

macgills avatar Mar 23 '20 09:03 macgills

Indeed, we must support big images at all stages. By the way some people upload all sorts of huge files in various formats via the Upload Wizard web interface, and use the app from time to time, having these files show up in the app's Contributions page. Also, huge images/etc may appear in search. So the app should not crash on any of these files.

nicolas-raoul avatar Mar 23 '20 09:03 nicolas-raoul

I tried to replace the PhotoView with DraweeView as suggested by @macgills and it resolves the problem of crashing. But, now the problem arises that the image does not load in DraweeView because of the URI . Also, the scaling of image is not working as expected.

mrudultora avatar Feb 21 '21 10:02 mrudultora

I have also noticed this issue and managed to found a solution but not sure if it's the best thing to do. I have disabled the hardware acceleration for uploadActivity by adding the android:hardwareAccelerated="false" attribute in Android Manifest File, Now it is working as expected and I am able to upload the image!

Pratham2305 avatar Feb 22 '21 08:02 Pratham2305

@Pratham2305 Yes, you're right, but there are other consequences of using android:hardwareAccelerated="false". So, I think it is not the best solution.

mrudultora avatar Feb 22 '21 09:02 mrudultora

@animeshk08 I unassign for now, but if you are you still working on this, please let us know. If no answer, someone else may be assigned to it. Thanks a lot. :-)

nicolas-raoul avatar Aug 20 '24 07:08 nicolas-raoul

I am not working on this. Please feel free to re-assign :)

animeshk08 avatar Aug 20 '24 07:08 animeshk08

Quite frequently reported in v6.0.2. We recently bumped up our target SDK with a few other changes for Android 15; not sure if that's related.

RitikaPahwa4444 avatar Oct 01 '25 21:10 RitikaPahwa4444

Is there any stack trace that seems to match this?

nicolas-raoul avatar Oct 02 '25 00:10 nicolas-raoul

Yes @nicolas-raoul. Here's one such report:

USER_COMMENT=I'M UPLOADING A PHOTO RELATED TO BUILDINGS EVENING SKY BUT IT KEEPS SHOWING ERROR WHILE UPLOADING IT
APP_VERSION_CODE=1058
APP_VERSION_NAME=6.0.2
ANDROID_VERSION=13
PHONE_MODEL=motorola edge 20 fusion
STACK_TRACE=java.lang.RuntimeException: Canvas: trying to draw too large(324000000bytes) bitmap.

at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:549)
at android.widget.ImageView.onDraw(ImageView.java:1446)
at android.view.View.draw(View.java:23301)
at android.view.View.updateDisplayListIfDirty(View.java:22168)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.draw(View.java:23304)
at android.view.View.updateDisplayListIfDirty(View.java:22168)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.draw(View.java:23304)
at androidx.viewpager.widget.ViewPager.draw(ViewPager.java:2426)
at android.view.View.updateDisplayListIfDirty(View.java:22168)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.updateDisplayListIfDirty(View.java:22159)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at 
android.view.View.updateDisplayListIfDirty(View.java:22159)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.updateDisplayListIfDirty(View.java:22159)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.updateDisplayListIfDirty(View.java:22159)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.updateDisplayListIfDirty(View.java:22159)
at android.view.View.draw(View.java:23032)
at android.view.ViewGroup.drawChild(ViewGroup.java:4541)
at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:4302)
at android.view.View.draw(View.java:23304)
at com.android.internal.policy.DecorView.draw(DecorView.java:854)
at android.view.View.updateDisplayListIfDirty(View.java:22168)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:689)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:695)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:793)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:5064)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4773)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3983)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2580)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9586)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
at android.view.Choreographer.doCallbacks(Choreographer.java:899)
at
android.view.Choreographer.doFrame(Choreographer.java:832)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
at android.os.Handler.handleCallback(Handler.java:984)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loopOnce(Looper.java:238)
at android.os.Looper.loop(Looper.java:357)
at android.app.ActivityThread.main(ActivityThread.java:8194)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)

RitikaPahwa4444 avatar Oct 02 '25 05:10 RitikaPahwa4444

I have disabled the hardware acceleration for uploadActivity by adding the android:hardwareAccelerated="false" attribute in Android Manifest File, Now it is working as expected and I am able to upload the image!

Did it originate from here? 🤔 If yes, it's better to revert the change in the manifest and disable the animation added recently until we find the right solve. Seems like those changes broke the flow in v6.0.2. @rohit9625 what are your thoughts on this?

RitikaPahwa4444 avatar Oct 05 '25 06:10 RitikaPahwa4444

It could be, but I don't think so because the error was reported 6 years ago as well, when we already had hardware acceleration disabled for UploadActivity. However, it is worth trying after disabling. From the logs, it seems that the image was quite large (324 MB). How could an image be this large?

Can you reproduce this issue, @RitikaPahwa4444? If yes, please share the image and repro steps.

rohit9625 avatar Oct 05 '25 06:10 rohit9625

The image size indeed seems quite big and that was the first thing even I noticed. But there are several crash reports lined up this time. My only concern is that it surfaced up again after we released those changes. So I would prefer to revert in this release until we find the solve.

RitikaPahwa4444 avatar Oct 05 '25 06:10 RitikaPahwa4444

If it's because hardware acceleration, then this could be the reason:

  • Hardware acceleration = faster UI rendering, but strict GPU limits.
  • Software rendering = slower, but tolerant of large offscreen bitmaps.

So, either we can disable the harware acceleration or resize the image while rendering. I can try this if I found this large image on internet.

rohit9625 avatar Oct 05 '25 06:10 rohit9625

The image size indeed seems quite big and that was the first thing even I noticed. But there are several crash reports lined up this time. My only concern is that it surfaced up again after we released those changes. So I would prefer to revert in this release until we find the solve.

Okay, I'll try to repro this issue and report the findings today. Also, if resizing the image while rendering solves the problem. Then we are good to go :)

rohit9625 avatar Oct 05 '25 06:10 rohit9625

I see 141 MB as well in one of the reports. The images shot with my 50 MP camera do take > 10 MB per image on my device, not sure about newer cameras with higher resolution. I'll share the minimum number once I go through all the reports again.

RitikaPahwa4444 avatar Oct 05 '25 06:10 RitikaPahwa4444

I see 141 MB as well in one of the reports. The images shot with my 50 MP camera do take > 10 MB per image on my device, not sure about newer cameras with higher resolution. I'll share the minimum number once I go through all the reports again.

Oh, so this issue can be repeated with multiple images as well? I thought it's just one image with size 144 mb.

rohit9625 avatar Oct 05 '25 06:10 rohit9625

I can only find image files of 100MB max. I tried uploading two 100MB files simultaneously to repeat the crash on my end, but the UploadActivity got closed without any crash logs, and the app navigated to the Contributions screen.

https://github.com/user-attachments/assets/7a858b87-c7c9-4382-824c-2c51e9d5c682

rohit9625 avatar Oct 08 '25 14:10 rohit9625

When testing on a physical device, the app is crashing completely but I couldn't see any logs and that ACRA dialog also doesn't appear.

rohit9625 avatar Oct 08 '25 14:10 rohit9625

Tested with android:hardwareAccelerated="false" for UploadActivity but still the same behavior. What about limiting the large image uploads or resizing them to the maximum acceptable size. Uploading 100MB files are not very common I guess. What do you think, @RitikaPahwa4444?

rohit9625 avatar Oct 08 '25 14:10 rohit9625