OutOfMemoryError when parsing large JSON in Android

Steps to reproduce

I am encountering a java.lang.OutOfMemoryError in my Android application. It appears to happen when attempting to parse a large JSON string, likely originating from a file read operation via FileUtils (Cordova environment).

Actual result

The log below indicates that the app crashed while trying to allocate ~150MB for a string operation inside JSONTokener.nextString. Although there were ~66MB of free memory, the allocation failed due to the Growth Limit being capped at 256MB.

The stack trace points to FileUtils, suggesting the issue occurs when reading a file and converting it directly into a JSONArray.

My Questions:

  1. Is there a way to handle large file parsing in FileUtils without loading the entire string into memory?
  2. Has this limit been addressed in newer versions of the app?
  3. Are there any known workarounds for this specific OOM scenario?

Thanks for any help.

Environment

Android mobile app, the version number of Dynalist is 1.4.19


Additional information

Error Log:

java.lang.OutOfMemoryError: Failed to allocate a 150994952 byte allocation with 66916568 free bytes and 63MB until OOM, target footprint 268435456, growth limit 268435456
	at java.util.Arrays.copyOf(Arrays.java:3766)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:542)
	at java.lang.StringBuilder.append(StringBuilder.java:176)
	at org.json.JSONTokener.nextString(JSONTokener.java:228)
	at org.json.JSONTokener.nextValue(JSONTokener.java:111)
	at org.json.JSONTokener.readArray(JSONTokener.java:440)
	at org.json.JSONTokener.nextValue(JSONTokener.java:107)
	at org.json.JSONArray.<init>(JSONArray.java:94)
	at org.json.JSONArray.<init>(JSONArray.java:110)
	at org.apache.cordova.file.FileUtils$25.run(FileUtils.java:663)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
	at java.lang.Thread.run(Thread.java:1012)


Additional comments

The large file was imported from WorkFlowy containing years of records, even though it has very few image or document attachments.

PPS: The large file behaves normally on the Windows desktop client and the web interface.

Yeah I think unfortunately the memory limitations on Android is fairly strict, you’re best to break up large files into a few smaller ones.