I'm writing app where user can take bunch of pictures (up to 20) and upload to server. Images need to be uploaded all together.
Here is my logic:
- Take each picture, display thumb on a screen and resize picture on SD to 800x600 with 90 quality
- Create object, populate properties (images) as Base64 string
- Serialize object using GSON
- Upload string
While testing I was getting errors "Out of Memory" when I was processing images. I thought and this is where all StackOverflow complains is - that it's some bug with BitmapFactory. Yes, error mostly shows up while resizing image but it is NOT related to this operation.
While I take pictures and process them (resize, etc) - heap size stays below 7-8mb. It's just 2-3Mb more than my usual app state.
When I submit those images to server and GSON + Base64 encoder comes into play - than it "explodes" and I get this:
Well - as you see - after process completed Allocated memory get's down as expected but Heap Size stays. Now, when I take more pictures or do something with app - I start to get those out of memory errors.
Here is my code to upload JSON. Any suggestions on improving it or handling something like that? Maybe I can stream JSON into file and do http from file or something?
wh开发者_StackOverflow社区ile (!c.isAfterLast())
{
String data = c.getString(colObjectData);
TrailerInspection trailerInspection = MyGsonWrapper.getMyGson().fromJson(data, TrailerInspection.class);
//Load image data
for (TrailerUnitInspection trailerUnitInspection : trailerInspection.UnitInspections)
{
for (FileContainer fileContainer : trailerUnitInspection.Images)
{
fileContainer.dataFromFile(mContext);
}
}
data = MyGsonWrapper.getMyGson().toJson(trailerInspection);
MyHttpResponse response = processPOST("/trips/" + c.getString(colTripId) + "/trailerinspection", data);
if (response.Code == HttpURLConnection.HTTP_OK)
{
processed.add(c.getString(colGId));
}
c.moveToNext();
}
c.close();
The problem is that you're creating and keeping whole string, which is prepared to sending, in internal memory.
String data = MyGsonWrapper.getMyGson().toJson(trailerInspection);
This string may be very large. You should stream your data in chunks to server.
I haven't used gson yet, but in docs I found something like JsonWriter. Take a look at this class.
UPDATE:
ContentProducer cp = new ContentProducer() {
public void writeTo(OutputStream outstream) throws IOException {
JsonWriter writer = new JsonWriter(new OutputStreamWriter(outstream, "UTF-8"));
// write code here
writer.flush();
}
};
HttpEntity entity = new EntityTemplate(cp);
HttpPost httppost = new HttpPost("http://server.address");
httppost.setEntity(entity);
精彩评论