Large files failing when trying to return JSONObject
Gillardo opened this issue · comments
NOTE: Yes i have already got the android largeHeap = true in my manifest file
Platform: Android
I am selecting a 46MB file so i can copy it using my own code. Problem is that this plugin is trying to return the data for the file when you pick the file, and this is causing the app to crash
java.lang.OutOfMemoryError: Failed to allocate a 256959896 byte allocation with 25165824 free bytes and 158MB until OOM, target footprint 395341816, growth limit 536870912
at java.util.Arrays.copyOf(Arrays.java:3257)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:137)
at org.apache.cordova.NativeToJsMessageQueue$JsMessage.buildJsMessage(NativeToJsMessageQueue.java:518)
at org.apache.cordova.NativeToJsMessageQueue$JsMessage.encodeAsJsMessage(NativeToJsMessageQueue.java:535)
at org.apache.cordova.NativeToJsMessageQueue.popAndEncodeAsJs(NativeToJsMessageQueue.java:191)
at org.apache.cordova.NativeToJsMessageQueue$EvalBridgeMode$1.run(NativeToJsMessageQueue.java:366)
at android.app.Activity.runOnUiThread(Activity.java:6974)
at org.apache.cordova.NativeToJsMessageQueue$EvalBridgeMode.onNativeToJsMessageAvailable(NativeToJsMessageQueue.java:364)
at org.apache.cordova.NativeToJsMessageQueue.enqueueMessage(NativeToJsMessageQueue.java:249)
at org.apache.cordova.NativeToJsMessageQueue.addPluginResult(NativeToJsMessageQueue.java:238)
at org.apache.cordova.CordovaWebViewImpl.sendPluginResult(CordovaWebViewImpl.java:311)
at org.apache.cordova.CallbackContext.sendPluginResult(CallbackContext.java:61)
at org.apache.cordova.CallbackContext.success(CallbackContext.java:79)
at com.cyph.cordova.Chooser.onActivityResult(Chooser.java:132)
If you look at line 132, you will see this line
this.callback.success(result.toString());
I belive this is because calling toString to create the JSON object as a string with this much data is too much.
Can i ask why the data is returned? Should this not be a parameter on the getFile
method? Or can we have another method getFileWithoutData instead to not break existing calls?
If i update my plugin file locally and change line 123 from
String base64 = Base64.encodeToString(bytes, Base64.DEFAULT);
to
String base64 = ""; // Base64.encodeToString(bytes, Base64.DEFAULT);
Then this now works
The following must be added to config.xml to prevent crashing when selecting large files on Android:
<platform name="android">
<edit-config
file="app/src/main/AndroidManifest.xml"
mode="merge"
target="/manifest/application">
<application android:largeHeap="true" />
</edit-config>
</platform>
In my case, files over 100 megabytes are selected without problems
I have mentioned < application android:largeHeap="true" >
still app crash when selecting 100MB+ size file.
any updates or known workarounds for this issue?
I guess it is possible to use getFileMetadata
which does not include the data, and then perform the binary data extraction within your own app (with error handling)