9
votes

Comment est-il possible de télécharger des fichiers volumineux avec Volley? ( Android )

Je souhaite télécharger des fichiers volumineux dans une requête POST à l'aide de Volley. J'ai essayé d'utiliser une bibliothèque VolleyMultiPartRequest , mais j'obtiens 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)

Toutes les bibliothèques comme VolleyPlus MultiPartRequest écrasent la fonction public byte[] getBody() . Cela semble être le problème, car si un fichier volumineux est converti en un tableau d'octets, il ne peut pas tenir dans la mémoire. Je dois envoyer la demande en morceaux. Comment est-ce possible?


2 commentaires

La dernière fois que j'ai utilisé volley, je n'ai trouvé aucune solution à ce problème, j'ai dû utiliser une autre bibliothèque juste pour le téléchargement.


D'accord: arrêtez d'utiliser Volley. Comme nous l'avons vu précédemment , OkHttp ne lit pas l'intégralité du contenu à télécharger en mémoire, mais fonctionne plutôt en utilisant des flux.


3 Réponses :


2
votes

Lisez ceci: Volley Issue

À partir du lien: "Il [volée] nécessite intrinsèquement que la requête / réponse complète soit stockable en mémoire, et pour les téléchargements vidéo, il est beaucoup plus logique de les diffuser de manière incrémentielle sur le réseau à partir d'une autre source (disque), pour prendre en charge la reprise de des téléchargements partiels, etc., d'une manière que l'API de Volley ne prend pas en charge par nature. "


0 commentaires

1
votes

Comme @CommonsWare l'a mentionné dans le commentaire ci-dessous la question - vous devriez abandonner Volley (du moins pour le moment). Il y a quelque temps, ils voulaient même désapprouver Volley car cela dépend d'Apache HttpClient qui est obsolète depuis l'API 23, mais pour autant que je sache, Google le prend toujours en charge et a l'intention de le rendre plus moderne.

Pour l'instant, tenez-vous-en au Retrofit et / ou à OkHttp sous- jacent qui tirent parti du chargement / téléchargement de flux plutôt que d'une charge complète en mémoire. Avec ceux-ci, vous n'aurez pas de tels problèmes.


0 commentaires

2
votes

Volley a quelques problèmes connus avec l'uplaod de fichiers volumineux.

Utilisez le téléchargement de fichiers en plusieurs parties pour les fichiers volumineux, par exemple (avec mise à niveau):

public interface FileUploadService {

    @Multipart
    @POST("/upload")
    void upload(@Part("myfile") TypedFile file,
                @Part("description") String description,
                Callback<String> cb);
}

Pour votre référence: https://futurestud.io/blog/retrofit-how-to-upload-files/


0 commentaires