我正在开发一个连接到Web服务器并接收二进制数据的项目。我的问题是当我从Web服务器下载数据时。如果我发送登录请求或激活某些设置,则没有问题。但是当我发送下载二进制数据的请求时,它会给我一个OutOfMemoryException
。这是我正在使用的代码:
public byte[] activateColl(int index) {
createCancelProgressDialog("","Communcating with you...","Cancel");
byte[] buffer = new byte[1024];
try {
httpclient = new DefaultHttpClient();
httppost = new HttpPost("http://www.rpc.frbr.com");
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
String deviceId = tm.getDeviceId();
Log.w("device_identificator","device_identificator : "+deviceId);
String resolution = Integer.toString(getWindow().getWindowManager().getDefaultDisplay().getWidth())+ "x" +
Integer.toString(getWindow().getWindowManager().getDefaultDisplay().getHeight());
Log.w("device_resolution","device_resolution : "+resolution);
String version = "Android " + Build.VERSION.RELEASE;
Log.w("device_os_type","device_os_type : "+version);
Log.w("device_identification_string","device_identification_string : "+version);
String locale = getResources().getConfiguration().locale.toString();
Log.w("set_locale","set_locale : "+locale);
String clientApiVersion = null;
PackageManager pm = this.getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(this.getPackageName(), 0);
clientApiVersion = packageInfo.versionName;
Log.w("client_api_ver","client_api_ver : "+clientApiVersion);
hash = getAuthHash();
TelephonyManager tMgr =(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
phoneNumber = tMgr.getLine1Number();
Log.i("Phone","Phone Number : "+phoneNumber);
Log.w("INDEX","INDEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX : "+Integer.toString(index));
String timestampSQL = "SELECT dbTimestamp FROM users";
Cursor cursor = systemDbHelper.executeSQLQuery(timestampSQL);
if(cursor.getCount()==0){
Log.i("Cursor","TimeStamp Cursor Empty!");
} else if(cursor.getCount()>0){
cursor.moveToFirst();
timeStamp = cursor.getString(cursor.getColumnIndex("dbTimestamp"));
}
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("debug_data","1"));
postParameters.add(new BasicNameValuePair("client_auth_hash", hash));
postParameters.add(new BasicNameValuePair("timestamp", timeStamp));
postParameters.add(new BasicNameValuePair("mobile_phone", phoneNumber));
postParameters.add(new BasicNameValuePair("activate_collections",Integer.toString(index)));
postParameters.add(new BasicNameValuePair("device_identificator", deviceId));
postParameters.add(new BasicNameValuePair("device_resolution", resolution));
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
HttpResponse response = httpclient.execute(httppost);
Log.w("Response ","Status line : "+ response.getStatusLine().toString());
buffer = EntityUtils.toByteArray(response.getEntity());
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return buffer;
}
LogCat出错:
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): java.lang.OutOfMemoryError
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:57)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:75)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at org.apache.http.util.EntityUtils.toByteArray(EntityUtils.java:80)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at com.stampii.stampii.synchronization.Synchronization.deactivateColl(Synchronization.java:843)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at com.stampii.stampii.synchronization.Synchronization.onCreate(Synchronization.java:116)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.os.Handler.dispatchMessage(Handler.java:99)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.os.Looper.loop(Looper.java:144)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at android.app.ActivityThread.main(ActivityThread.java:4937)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at java.lang.reflect.Method.invokeNative(Native Method)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at java.lang.reflect.Method.invoke(Method.java:521)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-17 17:53:00.198: ERROR/AndroidRuntime(15486): at dalvik.system.NativeStart.main(Native Method)
任何想法如何解决?我试图将缓冲区的大小增加到50 * 1024,但仍无法帮助。
编辑:该行引发错误:
buffer = EntityUtils.toByteArray(response.getEntity());
答案 0 :(得分:1)
在Android上,您只有有限的堆大小,当您尝试解码实体时,它会耗尽。我认为你需要使用http chunking将你的数据发送到客户端(或者出错了,EntityUtils认为他们需要一个更大的数组。问题是一个字节数组,它要大到不小。看看这个帖子:
答案 1 :(得分:1)
好的,试试这个..
HttpResponse response = httpclient.execute(httppost);
// get response entity
HttpEntity entity = response.getEntity();
// convert entity response to string
if (entity != null)
{
InputStream is = entity.getContent();
// convert stream to string
result = convertStreamToString(is);
result = result.replace("\n", "");
}
适用于conversion of InputStream to String
public String convertStreamToString(InputStream inputStream)
{
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
return total.toString();
}
或
使用Apache Commons库(org.apache.commons.io.IOUtils)。
String total = IOUtils.toString(inputStream);
或只是写入临时文件,
HttpEntity.writeTo(OutputStream);
根据用户Philipp Reichart建议,来自org.apache.http.util
;
EntityUtils.toString();
是允许encoding format with String Conversion
。
让我知道你仍然得到OutOfMemory Error
。
感谢。