nextcloud / android

📱 Nextcloud Android app
https://play.google.com/store/apps/details?id=com.nextcloud.client
GNU General Public License v2.0
4.06k stars 1.74k forks source link

app crash on browsing folder with a lot of photos #10338

Open vladbejenaru opened 2 years ago

vladbejenaru commented 2 years ago

Cause of error

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@fb5b3d8 rejected from java.util.concurrent.ThreadPoolExecutor@e399331[Running, pool size = 17, active threads = 17, queued tasks = 128, completed tasks = 26]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2078)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:843)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1389)
    at android.os.AsyncTask.executeOnExecutor(Unknown Source:34)
    at com.owncloud.android.utils.DisplayUtils.setThumbnail(DisplayUtils.java:952)
    at com.owncloud.android.ui.adapter.OCFileListDelegate.bindGridViewHolder(OCFileListDelegate.kt:92)
    at com.owncloud.android.ui.adapter.OCFileListAdapter.onBindViewHolder(OCFileListAdapter.java:366)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
    at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
    at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
    at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
    at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
    at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
    at android.os.Handler.handleCallback(Unknown Source:2)
    at android.os.Handler.dispatchMessage(Unknown Source:4)
    at android.os.Looper.loop(Unknown Source:152)
    at android.app.ActivityThread.main(Unknown Source:65)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
    at com.android.internal.os.ZygoteInit.main(Unknown Source:338)

App information

Device information

Firmware

ezaquarii commented 2 years ago

From https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html:

New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated. In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler.

Exception in thread "main" java.util.concurrent.RejectedExecutionException: 
Task android.os.AsyncTask$3@fb5b3d8 rejected from java.util.concurrent.ThreadPoolExecutor@e399331[Running, pool size = 17, active threads = 17, queued tasks = 128, completed tasks = 26]

So it seems that the queue is full. This is Android limitation (look for MAXIMUM_POOL_SIZE = 128;) It seems that the app is doing a lot of async work in the background and similar errors will be popping up as time passes.

The solution is simple: stop using async tasks. AsyncTask is badly designed and deprecated in favour of generic concurrency primitives. I see little sense in tacking this specific crash - it require more comprehensive overhaul.

@AlvaroBrey @tobiasKaminsky FYI

ezaquarii commented 2 years ago

@vladbejenaru How often does it happen? Was it a one-off event?

vladbejenaru commented 2 years ago

hi. It happened only once. Suggestion to post here came from the crash and I thought it may help you.

ezaquarii commented 2 years ago

@vladbejenaru

It does, thank you. It's not that the bug is invalid - the problem is more widespread that this crash stack trace suggests.

Thank you for reporting it.

svenb1234 commented 2 years ago

Is #10284 a dup?

svenb1234 commented 2 years ago

10203 as well?

ezaquarii commented 2 years ago

@svenb1234 Yes, this is the same problem.

We can try moving those tasks to a dedicated thread pool. That does not solve the fundamental issue of launching so many tasks that are not interruptible. If we make the queue deeper, we can cause some performance degradation when user scrolls down large list. If the task involves network I/O, this can get serious.

Alternatively, we could just catch this exception and do not show a miniature. That would cause slight visual degradation, but won't cause excessive CPU load with large amount of bg tasks.

@AlvaroBrey @tobiasKaminsky comments?

AlvaroBrey commented 2 years ago

I can't figure out how to trigger this, I get the following when trying to scroll fast enough to reach 128 tasks:

2022-06-08 13:11:29.884 8801-8801/com.nextcloud.client V/ThumbnailsCacheManager: Cancelled generation of thumbnail for a reused imageView

It looks like this cancellation might be failing in some cases?

meldarionqeusse commented 2 years ago

I have been getting this issue for the past month dismissed it at first cause I couldn't find a similar issue happening to someone else and because it happened once. But now it's happening everytime.

What's more I am thinking that it's bricking my raspberry pi after a few minutes that the bug occurs. Forcing me to restart.

This is the error log generated

Cause of error

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@10790db rejected from java.util.concurrent.ThreadPoolExecutor@2bd9778[Running, pool size = 17, active threads = 17, queued tasks = 128, completed tasks = 224]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2085)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:848)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1394)
    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:651)
    at com.owncloud.android.utils.DisplayUtils.setThumbnail(DisplayUtils.java:952)
    at com.owncloud.android.ui.adapter.OCFileListDelegate.bindGridViewHolder(OCFileListDelegate.kt:92)
    at com.owncloud.android.ui.adapter.OCFileListAdapter.onBindViewHolder(OCFileListAdapter.java:366)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
    at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:572)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
    at androidx.recyclerview.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1395)
    at androidx.recyclerview.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1136)
    at androidx.recyclerview.widget.GridLayoutManager.scrollVerticallyBy(GridLayoutManager.java:386)
    at androidx.recyclerview.widget.RecyclerView.scrollStep(RecyclerView.java:1972)
    at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5476)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1004)
    at android.view.Choreographer.doCallbacks(Choreographer.java:816)
    at android.view.Choreographer.doFrame(Choreographer.java:748)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:990)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:280)
    at android.app.ActivityThread.main(ActivityThread.java:6706)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

App information

Device information

Firmware

meldarionqeusse commented 2 years ago

I have confirmed that the crash on the android app was causing issues on my raspberry pi and after some digging in /var/log/syslog I also found out that the raspberry pi was becoming undervolted when the crash happens. (I found out the my rpi became overclock to 1.8 GHz with the latest update so I brought it back to 1.5 GHz). I tried loading lots of photos on the android app and looking at the cpu load and temps and as soon as the crash happens all 4 cores were at 100% load image

I am still unsure why the crash is causing this to it seems like linux is being rebooted. I wonder if others experiencing the same issues are getting the same errors you can check with "grep "Booting Linux on physical" /var/log/syslog -a"

Jun 10 08:27:36 raspberrypi mtp-probe: checking bus 2, device 2: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-2"
Jun 10 08:27:36 raspberrypi mtp-probe: bus: 2, device: 2 was not an MTP device
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] Linux version 5.15.32-v8+ (dom@buildbot) (aarch64-linux-gnu-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1538 SMP PREEMPT Thu Mar 31 19:40:39 BST 2022
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] random: fast init done
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] Machine model: Raspberry Pi 4 Model B Rev 1.2
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] efi: UEFI not found.
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] Reserved memory: created CMA memory pool at 0x000000001ac00000, size 320 MiB
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
Jun 10 08:27:36 raspberrypi kernel: [    0.000000] Zone ranges:
Jun 10 08:27:36 raspberrypi kernel: [    0.000000]   DMA      [mem 0x0000000000000000-0x000000003fffffff]
Jun 10 08:27:36 raspberrypi kernel: [    0.000000]   DMA32    [mem 0x0000000040000000-0x00000000fbffffff]
Jun 10 08:27:36 raspberrypi kernel: [    0.000000]   Normal   empty
AlvaroBrey commented 2 years ago

I am still unsure why the crash is causing this to it seems like linux is being rebooted. I wonder if others experiencing the same issues are getting the same errors you can check with "grep "Booting Linux on physical" /var/log/syslog -a"

Most likely your raspberry crashing is not caused by the app crashing, but rather both things are caused by the same thing: too many parallel requests. Your raspberry is likely overwhelmed trying to generate thumbnails for way too many images at the same time. If you have it undervolted or use a cheap AC adapter, the high CPU load will crash the raspberry. However, this is not a raspberry pi repository; so I've marked your second comment as offtopic (same for this one).

AlvaroBrey commented 2 years ago

Can any of the affected users give clear reproduction steps? Is it browsing in the normal files browser, or in the gallery/media screen? Also, does it happen immediately on opening the folder, or after some scrolling?

ezaquarii commented 2 years ago

Try putting a sleep into the thumbnail async task to slow it down a bit. I think async taks are not cancelled so they should easily accumulate triggering the condition.

meldarionqeusse commented 2 years ago

@AlvaroBrey no I am not using the media just browsing the folder normally. The issue does not happen with the media folder. I am not sure if videos play here but I tried to caputre it here https://user-images.githubusercontent.com/21668964/173192301-512e5d3a-9436-4abb-8474-4e3dbf9653b1.mp4

godfuture commented 1 year ago

Same issue here with Android 3.22.1 from PlayStore. Folder with many fotos. Thumbnails are missing. Thumbnails start to pop up, but the NC app gets a bit sluggish. It starts to hang from time to time. Scrolling is stuttering. Still, close to none network traffic, even in LAN environment. Sooner or later the app crashes with the stack seen above.

yanakis71 commented 1 year ago

For this issue/reason I gave up on Nextcloud (Docker install). I wanted to replace Onedrive but Android app is crashing every time on my 4000+ pics folder. Additionally, thumbnails display is painfully slow

pgorgita commented 2 weeks ago

I have the same problem, always when trying to explore a Folder with all my Fotos and Videos:

Cause of error

Exception in thread "main" java.lang.OutOfMemoryError: Failed to allocate a 16 byte allocation with 977488 free bytes and 954KB until OOM, target footprint 536870912, growth limit 536870912; giving up on allocation because <1% of heap free after GC.
    at java.lang.Float.valueOf(Float.java:467)
    at android.animation.PropertyValuesHolder$FloatPropertyValuesHolder.getAnimatedValue(PropertyValuesHolder.java:1359)
    at android.animation.ValueAnimator.getAnimatedValue(ValueAnimator.java:948)
    at com.elyeproj.loaderviewlibrary.LoaderController.onAnimationUpdate(LoaderController.java:136)
    at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1653)
    at android.animation.ValueAnimator.animateBasedOnTime(ValueAnimator.java:1440)
    at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1572)
    at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:307)
    at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
    at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1299)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1309)
    at android.view.Choreographer.doCallbacks(Choreographer.java:923)
    at android.view.Choreographer.doFrame(Choreographer.java:847)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1283)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8762)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

App information

Device information

Firmware

godfuture commented 2 weeks ago

For this issue/reason I gave up on Nextcloud (Docker install). I wanted to replace Onedrive but Android app is crashing every time on my 4000+ pics folder. Additionally, thumbnails display is painfully slow

You are not the only one. The nextcloud app is still half baked. I wonder, and I guess you do as well, that nextcloud is already a really big project, but still the mobile app is behaving beta....sometimes even alpha. Missing thumbnails, crashing, slow, hanging, strange implementation of android notifications, some features just dont work yet. In short - unrealiable at best.

For realiable file upload, I am using FolderSync (https://play.google.com/store/apps/details?id=dk.tacit.android.foldersync.lite&pcampaignid=web_share).