通过httpPost上传base64映像到服务器的问题
问题描述:
我正在使用JSON和HttpPost将本地SQLite数据库的全部内容发送到远程MySQL数据库的应用程序原型。通过httpPost上传base64映像到服务器的问题
一切工作正常的文本数据。 现在我向派对中添加了图像,但我可以将图像作为base64字符串添加到我发送的JSON中。我的图像是800 x 600像素,每个大小或多或少500kb。
如果我手动将我的应用程序生成的JSON粘贴到网页上,那很好,我得到了我的图像和其他一切。
使用的应用程序上传脚本,我尝试上传的JSON字符串4张图片,但应用程序卡住我的进度对话框和logcat的推移遍地显示这一点:
11-15 14:32:27.809: I/dalvikvm-heap(15562): Grow heap (frag case) to 21.964MB for 2680048-byte allocation
11-15 14:32:27.840: D/dalvikvm(15562): GC_CONCURRENT freed 1744K, 30% free 20666K/29447K, paused 2ms+3ms
11-15 14:32:27.879: D/dalvikvm(15562): GC_FOR_ALLOC freed 4362K, 39% free 18049K/29447K, paused 16ms
11-15 14:32:27.918: D/dalvikvm(15562): GC_FOR_ALLOC freed 0K, 33% free 19794K/29447K, paused 22ms
11-15 14:32:27.918: I/dalvikvm-heap(15562): Grow heap (frag case) to 21.964MB for 2680276-byte allocation
11-15 14:32:27.958: D/dalvikvm(15562): GC_CONCURRENT freed 1744K, 30% free 20667K/29447K, paused 1ms+4ms
11-15 14:32:27.997: D/dalvikvm(15562): GC_FOR_ALLOC freed 4362K, 39% free 18049K/29447K, paused 17ms
11-15 14:32:28.028: D/dalvikvm(15562): GC_FOR_ALLOC freed 0K, 33% free 19795K/29447K, paused 17ms
,并继续永远。我敢打赌,这些图像太大了,无法用这种方式发送,或者我在某个地方泄漏了内存。
将大尺寸图像和JSON数据一起上传到服务器会更好吗?否则,我该如何避免内存泄漏?
的代码是非常标准...
从光标到JSON:
private JSONObject get_images_data_JSON(Cursor c) {
JSONObject image_jo = new JSONObject();
//get unit identifier
long unit_identifier = c.getLong(c.getColumnIndex("_id"));
//set unit details
try {
image_jo.put("_id", unit_identifier);
image_jo.put("unit_id", c.getLong(c.getColumnIndex("unit_id")));
//encode blob in Base64 for json parsing
String encodedImage = Base64.encodeToString(c.getBlob(c.getColumnIndex("image")), Base64.DEFAULT);
image_jo.put("image", encodedImage);
image_jo.put("caption", c.getString(c.getColumnIndex("caption")));
} catch (JSONException e) {
e.printStackTrace();
}
return image_jo;
}//end get_images_data_JSON
和POST功能:
public String postData(JSONArray array) {
String responseMessage = "";
//set connection timeout values
HttpParams myParams = new BasicHttpParams();
//set timeout in milliseconds until a connection is established
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
//set timeout for waiting data
HttpConnectionParams.setSoTimeout(myParams, 10000);
HttpClient httpclient = new DefaultHttpClient(myParams);
//Get a string out of the JSONArray
String json = array.toString();
try {
HttpPost httppost = new HttpPost(URL);
httppost.setHeader("Content-type", "application/json");
StringEntity se = new StringEntity(json);
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.setEntity(se);
HttpResponse response = httpclient.execute(httppost);
InputStream inputStream = response.getEntity().getContent();
responseMessage = inputStreamToString(inputStream);
//log out response from server
longInfo(responseMessage);
}
//show error if connection not working
catch (SocketTimeoutException e) {
e.printStackTrace();
responseMessage = "unreachable";
}
catch (ConnectTimeoutException e) {
e.printStackTrace();
responseMessage = "unreachable";
}
catch (Exception e) {
e.printStackTrace();
responseMessage = "unreachable";
}
return responseMessage;
}
任何帮助,将不胜感激
答
您的解决方案只是加载所有要发送到内存中的数据。这几乎不可扩展。考虑使用多部分实体。
File image1;
MultipartEntity entity = new MultipartEntity();
entity.addPart("json", new StringBody(serializedJson, Charset.forName("UTF-8"));
entity.addPart("image1", new FileBody(image1, "application/octet-stream");
这个例子显示了我即将发送磁盘上可用文件的情况。通过创建自己的AbstractContentBody实例,你应该能够发送一些东西位于你的分贝,而不消耗太多的内存...
答
对于任何人来到这里,我解决了所有问题,遵循Vajk的建议,这是我的新POST功能:
public String postData(Cursor images, JSONArray json_array) {
int counter = 0;
String responseMessage = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL);
//convert JSON array to String
String json_encoded_string = json_array.toString();
//MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
MultipartEntity entity = new MultipartEntity();
//add json data
entity.addPart("json", new StringBody(json_encoded_string));
//get all images plus data and add them to the Multipart Entity
for (images_cursor.moveToFirst(); !images_cursor.isAfterLast(); images_cursor.moveToNext()) {
counter++;
//Get image as byte array
byte[] image_ba = images_cursor.getBlob(images_cursor.getColumnIndex("image"));
long image_unit_id = images_cursor.getLong(images_cursor.getColumnIndex("unit_id"));
String image_caption = images_cursor.getString(images_cursor.getColumnIndex("caption"));
//add image to multipart
entity.addPart("image" + counter, new ByteArrayBody(image_ba, "image" + counter + ".jpg"));
//add unit _id to multipart
entity.addPart("image_unit_id" + counter, new StringBody(String.valueOf(image_unit_id)));
//add caption to multipart
entity.addPart("image_caption" + counter, new StringBody(String.valueOf(image_caption)));
}
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
InputStream inputStream = response.getEntity().getContent();
responseMessage = inputStreamToString(inputStream);
//log out response from server
longInfo(responseMessage);
}
//show error if connection not working
catch (SocketTimeoutException e) {
e.printStackTrace();
responseMessage = "unreachable";
}
catch (ConnectTimeoutException e) {
e.printStackTrace();
responseMessage = "unreachable";
}
catch (Exception e) {
e.printStackTrace();
responseMessage = "unreachable";
}
return responseMessage;
}
有人可能会发现这很有用;)
你应该多考虑。这对你正在尝试做的事更适合。 – njzk2