Me gustaría cargar archivos grandes en una solicitud POST usando Volley. Traté de usar una biblioteca VolleyMultiPartRequest , pero obtengo java.lang.OutOfMemoryError :
2020-11-13 19:14:06.636 18802-18802/com.example.myproject E/MainActivity: Tried to start foreground service from background 2020-11-13 19:14:09.730 18802-19082/com.example.myproject E/AndroidRuntime: FATAL EXCEPTION: Thread-15 Process: com.example.myproject, PID: 18802 java.lang.OutOfMemoryError: Failed to allocate a 303955984 byte allocation with 8388608 free bytes and 108MB until OOM, max allowed footprint 162626224, growth limit 268435456 at java.util.Arrays.copyOf(Arrays.java:3164) at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118) at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93) at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153) at com.example.myproject.utils.VolleyMultiPartRequest2.getBody(VolleyMultiPartRequest2.java:109) at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:275) at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:249) at com.android.volley.toolbox.HurlStack.executeRequest(HurlStack.java:94) at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:123) at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:131) at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:111) at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:90) Todas las bibliotecas como VolleyPlus MultiPartRequest anulan la función public byte[] getBody() . Este parece ser el problema, porque si un archivo grande se convierte en una matriz de bytes, entonces no cabe en la memoria. Necesito enviar la solicitud en trozos. ¿Cómo es eso posible?
Volley tiene algunos problemas conocidos con la carga de archivos grandes.
Use la carga de archivos de varias partes para archivos grandes, por ejemplo (con actualización):
public interface FileUploadService { @Multipart @POST("/upload") void upload(@Part("myfile") TypedFile file, @Part("description") String description, Callback<String> cb); }Para su referencia: https://futurestud.io/blog/retrofit-how-to-upload-files/
Lea esto: Problema Volley
Desde el enlace: "[Volley] requiere inherentemente que la solicitud/respuesta completa se pueda almacenar en la memoria, y para las cargas de video tiene mucho más sentido transmitirlas de manera incremental a través de la red desde otra fuente (es decir, disco), para respaldar la reanudación de cargas parciales, etc., de una manera que la API de Volley no admite inherentemente".
Como @CommonsWare mencionó en el comentario debajo de la pregunta, debe dejar Volley (al menos por ahora). Hace algún tiempo, incluso querían desaprobar Volley porque depende de Apache HttpClient, que está en desuso desde la API 23, pero que yo sepa, Google todavía lo admite y tiene intenciones de hacerlo más moderno.
Por ahora, apéguese a Retrofit y/o OkHttp subyacente que aprovechan la carga/descarga de secuencias en lugar de la carga completa en la memoria. Con esos no tendrás tales problemas.