cyph / cordova-plugin-chooser

Cordova file chooser plugin.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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>

https://ionicframework.com/docs/native/chooser

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.

commented

any updates or known workarounds for this issue?

commented

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)