2011-07-07 2 views
7

J'ai besoin d'obtenir des images ainsi que d'autres données (très similaire à l'email avec pièces jointes) sur le serveur. Je dois également le faire de manière fiable afin que je puisse réessayer, etc. en cas d'échec.Android télécharger des images sur le serveur de la manière la plus efficace

Serveur est serveur REST WCF et je fais beaucoup d'autres communications avec lui (JSON), mais a juste obtenu cette nouvelle exigence pour télécharger des images.

Depuis que j'utilise JSON pour publier des données sur mon serveur - j'utilise GSON côté Android pour sérialiser les données.

Voici comment je l'ai mis en œuvre jusqu'à présent (tout le reste fonctionne de cette façon mais je commence avec des images)

  1. champs d'activité de remplissage de l'utilisateur (données texte)
  2. utilisateur prend une photo (s) via les intentions de la caméra. Actuellement, je viens d'utiliser 1 fichier pour les images
  3. Je prends l'image de SDCard, charge/redimensionner - représenterez sur ImageView et stocker dans l'octet []
  4. utilisateur soumet - Je prends toutes les données ainsi que des images de l'octet [] et mis dans Java objet
  5. convertisseur Appel GSON et objet sérialisation
  6. Enregistrer objet dans SQLite
  7. AsyncTask regarde dans SQLite pour les enregistrements, ouvre le curseur et obtenir le texte de
  8. AsyncTask crée des données texte HttpConnection et messages sur mon serveur.
  9. LA FIN

maintenant à mes problèmes .. Il est évident que sur # 3 - I "exploser" ram avec mes tableaux d'octets. Parfois, je sens même que mon Nexus S devient lent. Mais en faisant cela - j'évite de remplir la carte SD ou le dossier de l'application avec beaucoup de fichiers. Je prends une photo et je l'attrape. L'image suivante écrasera la précédente.

Étape 5 EST lente. Je n'ai pas essayé le sérialiseur personnalisé sur GSON et au lieu de sérialiser le tableau d'octets dans quelque chose comme [1, -100,123, -12] je peux obtenir une taille beaucoup plus petite avec Base64 mais quand même. Ce sera lent. Et je peux avoir jusqu'à 20 images ...

L'étape # 6 ne pose aucun problème. Mais avec une certaine taille (j'ai essayé 300px image) j'ai commencé à l'erreur à l'étape 7 sur OpenCursor

07-06 20:28:47.113: ERROR/CursorWindow(16292): need to grow: mSize = 1048576, size = 925630, freeSpace() = 402958, numRows = 2 
07-06 20:28:47.113: ERROR/CursorWindow(16292): not growing since there are already 2 row(s), max size 1048576 
07-06 20:28:47.113: ERROR/Cursor(16292): Failed allocating 925630 bytes for text/blob at 1,1 

Donc, tout cela est quelque chose que je ne l'aime. Idéalement, je veux que toutes les données soient téléchargées en une seule pièce sur le serveur.

Je pensais peut-être stocker des images horodatées sur la carte SD et ne stocker que leur nom en DB. Que je les traiterais juste avant d'envoyer au serveur. Et en cas de succès, je supprimerais ces images. Ce type de logique rendra le schéma SQLite beaucoup plus complexe mais peut-être n'y a-t-il pas de meilleur moyen ?! Je suppose que je suis à la recherche de meilleures pratiques pour gérer les images.Comment faire followin avec utilisation de la mémoire/CPU minimale:

  1. Prenez la photo
  2. miniature Afficher
  3. Redimensionner
  4. Envoyer à un serveur

EDIT 1:

Actuellement Je recherche la possibilité de télécharger shizang entier comme un message MIME en plusieurs parties. Cela nécessiterait l'ajout de certains JAR à mon package Android. Aussi je ne suis pas sûr de savoir comment sera l'efficacité du code Apache pour charger des images et de les envoyer (je pense mieux que mon code) http://okandroidletsgo.wordpress.com/2011/05/30/android-to-wcf-streaming-multi-part-binary-images/

Et que je dois traiter avec l'analyse syntaxique tout cela sur le côté WCF car il n'y a façon de le faire avec le framework .NET intégré.

http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html

VOUS S'IL VOUS PLAÎT TELL ME SI CE ESSAYÉ!

EDIT 2:

MIME est pas bon. Il n'y a pas de point car il sérialise binaire en utilisant base64 qui est la même chose ..

+1

Vous sauvegardez donc l'image dans la base de données? Cela ferait exploser la taille de la base de données et vos utilisateurs se plaindront que l'application prend trop de place sur le stockage interne du téléphone et demandera le support app2sd de toute façon - pourquoi ne pas conserver les images sur la carte SD? –

+0

@denis J'ai trouvé que la limite de taille du curseur sur Android 1 Mo n'est pas seulement un problème avec le stockage interne, mais aussi je vais atteindre cette limite facilement en sauvegardant ce type de données dans SQLite. On dirait que l'utilisation de stockage externe est seulement la bonne façon de gérer de telles choses – katit

Répondre

16

Personne n'a répondu, mais voici ce que je pensais dure:

Règle n ° 1: Lorsque vous traitez avec des images - évitez d'utiliser des objets/mémoire. Cela semble évident mais ce n'est pas le cas. J'ai pensé que le redimensionnement de l'image à 800x600 est OK. Rien de plus gros - vous pouvez le laisser tel quel parce qu'il est possible de faire un flux http sur un fichier plus grand mais il est difficile de travailler avec des exceptions de MOO lorsque vous chargez des images en mémoire pour le traiter. utilisez JsonWriter pour remplir le flux. Sinon, la mémoire va exploser. Puis, passez ce flux dans HttpClient. JsonWriter écrira en morceaux et les données seront envoyées pendant le processus.

Règle n ° 3: Voir la règle n ° 2. Cela fonctionnera bien pour plusieurs petites images. De cette façon, GSON les sérialisera 1 par un et les introduira dans le flux. Chaque image sera chargée dans la mémoire int de toute façon. Règle n ° 4: C'est probablement la meilleure solution, mais nécessite plus de coordination avec le serveur. Images envoyées 1 par 1 avant l'envoi du message au serveur. Ils ont envoyé en flux sans aucun encodage. De cette façon, ils n'ont pas besoin d'être encodés en base64 et ils n'ont pas besoin d'être chargés en mémoire sur l'appareil. La taille de la transmission sera également plus petite. Lorsque toutes les images sont envoyées, affichez l'objet d'information principal et collectez tous les paquets ensemble sur le serveur.

Règle n ° 5: Oubliez le stockage blob dans SQLite

Bottom line:

  • Il est beaucoup moins cher en terme de ressources pour envoyer des images sans redimensionnement. Redimensionnement n'a de sens que lorsque l'image get à environ 800x600-ish
  • Envoi de plusieurs images dans un seul paquet est logique lorsque l'image get petit comme 600x400-ish
  • Dès que vous avez besoin de télécharger des fichiers - commencer à penser flux partout. NE PAS charger des choses en mémoire.
+0

Hey Katit, merci, semble logique. Y a-t-il quelque part un extrait pour le périphérique et le serveur? Je voudrais télécharger des images sur un serveur. J'utilise php maintenant. – Diego

Questions connexes