Android以最有效的方式将图片上传到服务器

我需要将图像和其他数据(非常类似于具有附件的电子邮件)一起传送到服务器。 我也需要以可靠的方式来做,所以我可以在失败后重试等。

服务器是WCF REST服务器,我做了很多其他的通信(JSON),但刚刚得到这个新的要求上传图像。

由于我使用JSON将数据发布到我的服务器 – 我使用Android上的GSON序列化数据。

下面是我到目前为止实现的方式(其他一切都是这样工作的,但我只是从图像开始)

  1. 用户填写活动字段(文本数据)
  2. 用户通过相机意图拍摄一些照片。 目前我只使用1个文件的照片
  3. 我从SDCard拍照,加载/resize – 在ImageView上显示并存储在字节[]中
  4. 用户提交 – 我将所有的数据与来自byte []的图像一起放入Java对象中
  5. 调用GSON转换器并序列化对象
  6. 将对象保存到SQLite中
  7. AsyncTask在SQLite中查找logging,打开光标并获取文本
  8. AsyncTask创buildHttpConnection并将文本数据发布到我的服务器。
  9. 结束

现在到我的问题..显然在#3 – 我“爆炸”内存与我的字节数组。 有时我甚至觉得我的Nexus S变得呆滞。 但通过这样做 – 我避免填充许多文件的SD卡或应用程序文件夹。 我拍照,而不是抓住它。 下一张图片将覆盖前一张。

步骤#5很慢。 我没有在GSON上尝试自定义序列化程序,而是将字节数组序列化为类似[1,-100,123,-12]的东西,但是仍然可以使用Base64获得更小的尺寸。 这将是缓慢的。 我可以有20个图像…

步骤#6没有问题。 但具有一定的尺寸(我尝试300px图像),我开始在OpenCursor的第7步中出现错误

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 

所以,这整件事情不是我喜欢的。 理想情况下,我希望所有的数据都被上传到服务器。

我想也许存储时间戳在SD卡上的图像,只存储他们的名字在数据库中。 比发送到服务器之前,我会处理它们。 如果成功,我会删除这些图片。 这种逻辑会使SQLite架构复杂得多,但也许没有更好的办法?!

我想我正在寻找处理图像的最佳做法。 如何以最小的内存/ CPU使用率进行跟进:

  1. 拍照片
  2. 显示缩略图
  3. 调整
  4. 发送到服务器

编辑1:

目前我正在研究将整个shizang上传为多部分MIME消息的可能性。 这将需要添加一些JAR的我的Android包。 此外,我不知道如何有效的Apache代码来加载图像和发送(我想比我的代码更好) http://okandroidletsgo.wordpress.com/2011/05/30/android-to-wcf-streaming-多部分二进制图像/

而且我将不得不在WCF端parsing所有这些,因为没有办法通过内置的.NET框架来实现。

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

请告诉我,如果你试试这个!

编辑2:

MIME是不好的。 这是没有意义的,因为它使用相同的东西Base64序列化二进制。

Solutions Collecting From Web of "Android以最有效的方式将图片上传到服务器"

没有人回答,但这里是我认真思考的问题:

规则1:处理图像时,避免使用对象/内存。 听起来很明显,但事实并非如此。 我认为将图像调整为800×600是可以的。 任何更大的东西 – 你可能会考虑把它留在原来的位置,因为可以在更大的文件上做httpstream,但是当你把图像加载到内存中进行处理时,很难处理OOMexception

规则2:使用GSON时 – 使用JsonWriter来填充stream。 否则内存将爆炸。 比通过该stream到HttpClient。 JsonWriter将以块forms写入,数据将在处理时发送。

规则#3:见规则#2。 这将工作正常多个小图像。 这样GSON就会把它们一个接一个串行化,然后送入stream中。 无论如何,每个图像都将被加载到内存中。

规则4:这可能是最好的解决scheme,但需要更多与服务器的协调。 在将消息发送到服务器之前,由1发送的图像。 他们发送没有任何编码stream。 这样,他们不必进行base64编码,并且不必将其加载到设备的内存中。 传输的大小也会变小。 当所有的图像发送 – 主要的信息对象,并收集所有的包在服务器上。

规则5:忘记在SQLite中存储BLOB

底线:

  • 无需resize,在资源方面发送图像便宜得多。 只有当图像达到800×600-ish时,resize才有意义
  • 当图像像600×400-ish一样小时,发送多个图像在一个包中是很有意义的
  • 只要你需要上传文件 – 开始思考stream到处。 不要将东西加载到内存中。