2010-12-15 148 views
2

Je reçois parfois un OutOfMemoryError lors de la publication d'un fichier volumineux dans Android. C'est le code que j'utilise. Est-ce que je fais quelque chose de mal?Publication d'un fichier volumineux dans Android

HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
con.setRequestMethod("POST"); 
con.setDoInput(true); 
con.setDoOutput(true); 
ostream = new DataOutputStream(con.getOutputStream()); 
byte[] buffer = new byte[1536]; 
int count; 
while ((count = fileInput.read(buffer)) != -1) { 
    ostream.write(buffer, 0, count); // This sometimes causes OutOfMemoryError 
} 
ostream.flush(); 

Would appelant ostream.flush() dans la boucle while faire du bien?

+1

Peut-être que vous utilisez trop de mémoire – Falmarri

+0

Comment puis-je utiliser moins pour faire cela? – hpique

+0

essayez de réduire la taille de votre tampon. – Ramp

Répondre

4

Si vous faites comme ça, tout le POST doit être tamponné en mémoire. En effet, il doit d'abord envoyer l'en-tête Content-Length. Au lieu de cela, je pense que vous voulez utiliser les bibliothèques HTTP Apache, y compris FileEntity. Cela permettra de comprendre la longueur avant de lire le fichier. Vous pouvez utiliser this answer comme point de départ. Mais le second paramètre du constructeur FileEntity devrait être un type mime (comme image/png, text/html, etc.).

+0

Merci Matthew. Ce comportement POST est-il documenté quelque part? Dans mon cas particulier, je ne connais pas la longueur du contenu à l'avance, car il est encodé à la volée, mais je me pencherai tout de même sur FileEntity. – hpique

+0

@hgpc, c'est fondamental pour le fonctionnement de HTTP. Les en-têtes vont toujours avant la demande ou la réponse. Le serveur peut utiliser l'en-tête 'Content-Length' (recommandé) ou se déconnecter à la fin de la réponse. Cependant, le client doit utiliser Content-Length, car il reste sur la ligne jusqu'à ce qu'il obtienne la réponse. Voir ceci [exemple POST session] (http://www.jmarshall.com/easy/http/#postmethod). –

+0

@hgpc, à quoi cela sert-il? –

2

La connexion HTTP est correcte, mais HTTPS déclenchera l'erreur Mémoire insuffisante car il y a un bug dans HttpsURLConnectionImpl.java dans Android 2.3.4 (vérifié sur ma tablette), et il est corrigé dans Android 4.1 (j'ai vérifié la source code). Par ailleurs, il devrait éviter de mettre en mémoire tampon toutes les données POST dans la RAM en ajoutant "con.setChunkedStreamingMode (0);" immédiatement après "con.setDoOutput (true);" déclaration.

+0

setChunkedStreamingMode pas de changement avec moi, merci – vuhung3990