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

[Bug] App crashes and becomes unable to start after importing images #205

Open
TCreopargh opened this issue Oct 18, 2024 · 2 comments
Open
Labels
bug Something isn't working

Comments

@TCreopargh
Copy link

TCreopargh commented Oct 18, 2024

Describe the bug
At first I tried to dump my wallpaper collection with 50,000+ images into the app, after clicking on the "+" button on top right it immediately crashes and is unable to start again until you wipe the data.
Then I tried to import images in smaller portions, a folder of hundereds at a time, but at a certain point I get this bug again. (It only crashes when you have this big album active. If you are on another smaller album, it's fine when you add folders, but the bug triggers after switching to the big album). I haven't found a way to stabily reproduce this problem and so far it doesn't seem to reproduce over a particular image or folder (No crash when I import that folder again). I got the stacktrace and hope you can figure out a way to solve this problem, as it's pretty critical if happened (all user data is lost). Really appreciated.

Crash log when I dump 50000+ images and hit the "+" button:

10-18 22:01:14.900 17347 17497 E AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-34
10-18 22:01:14.900 17347 17497 E AndroidRuntime: Process: com.anthonyla.paperize, PID: 17347
10-18 22:01:14.900 17347 17497 E AndroidRuntime: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=1
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:1051)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:862)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:145)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:252)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at android.database.AbstractCursor.moveToNext(AbstractCursor.java:301)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at Y2.k.a(Unknown Source:104)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at C2.p.call(Unknown Source:333)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at i2.b.o(Unknown Source:355)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at q5.a.n(Unknown Source:8)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at N5.J.run(Unknown Source:106)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at b.m.run(Unknown Source:23)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        at java.lang.Thread.run(Thread.java:1012)
10-18 22:01:14.900 17347 17497 E AndroidRuntime:        Suppressed: S5.e: [r0{Cancelling}@5fb12bd, Dispatchers.IO]

Crash log in the second case, when I import a small portion of images at a time. this stacktrace is only slightly different:

10-18 20:36:01.199 30880 30938 E AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-8
10-18 20:36:01.199 30880 30938 E AndroidRuntime: Process: com.anthonyla.paperize, PID: 30880
10-18 20:36:01.199 30880 30938 E AndroidRuntime: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=1, totalRows=2
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:1051)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:862)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:153)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:123)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:269)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at android.database.AbstractCursor.moveToNext(AbstractCursor.java:301)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at t2.J.M(Unknown Source:59)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at C2.p.call(Unknown Source:21)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at i2.b.o(Unknown Source:355)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at q5.a.n(Unknown Source:8)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at N5.J.run(Unknown Source:106)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at b.m.run(Unknown Source:23)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        at java.lang.Thread.run(Thread.java:1012)
10-18 20:36:01.199 30880 30938 E AndroidRuntime:        Suppressed: S5.e: [r0{Cancelling}@68ece9a, Dispatchers.IO]

To Reproduce
The problem seems to be related with having a massive amount of images in an album. Maybe try importing a very large image or a very large amount of images at a time.

Expected behavior
The app should successfully import a large number of files without crashing.

Screenshots
N/A

Smartphone (please complete the following information):

  • Device: Oneplus 12
  • OS: ColorOS 15 (Android 15.0)
  • Version: 2.3.2

Additional context

@TCreopargh TCreopargh added the bug Something isn't working label Oct 18, 2024
@Anthonyy232
Copy link
Owner

Heard your issue on the large amount of folders/wallpapers. To be honest, I'm kind of at a lost on what to do here. The issue with 50k images is that it breaks SQ-Lite's limit on the 1 mb limit per row (wallpapers are stored in wallpaperUri row per album). 50k image URIs seem to exceed the one million character limit. To fix this, I would probably have to restructure the backend which time is something I'm lacking currently, but I may revisit this at some point. Sincerely my apologies that this isn't higher priority but I would say this is quite an edge case as you mentioned.

@TCreopargh
Copy link
Author

Heard your issue on the large amount of folders/wallpapers. To be honest, I'm kind of at a lost on what to do here. The issue with 50k images is that it breaks SQ-Lite's limit on the 1 mb limit per row (wallpapers are stored in wallpaperUri row per album). 50k image URIs seem to exceed the one million character limit. To fix this, I would probably have to restructure the backend which time is something I'm lacking currently, but I may revisit this at some point. Sincerely my apologies that this isn't higher priority but I would say this is quite an edge case as you mentioned.

I understand that this is an edge case and it's because of how the database is structured and restructuring it takes a lot of work. However since the app crashes and is unable to recover any data when this limit is reached, it does create a significant issue for users encountering it. To help address this, here are a couple of potential workarounds I can think of that might be easier to implement:

  1. Limit the Number of Wallpapers per Gallery: You could set a maximum number of wallpapers allowed in each gallery, or simply add a warning if the user is attempting to import too many images that could exceed the SQLite limit, to prevent the app from crashing.
    Additionally, enabling multiple albums to be active at the same time could allow for a larger rotating image pool without requiring a major database change, this may come as an additional feature and is a lower priority. I'm not sure how complex this feature would be to add, but it could be a good compromise.

  2. URI Compression: Since most URIs likely share a common prefix, applying some kind of compression could allow each row to hold more URIs. This wouldn’t fully resolve the issue but could serve as a way to increase the gallery size limit before hitting the database restriction. I think there still needs to be a limit to prevent crashing.

  3. Storing URI in files: ChatGPT gave me this answer and I think it might be worth a try. If there are too many URIs in a single row, store the URIs in a file and leave a reference to that file in the database. this might still need a lot of work and testing but might be better than a complete restructure.

Thank you for considering these solutions, hope there's a helpful answer for you.

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

2 participants