Android HttpEntityUtils OutOfMemoryException
我正在开发一个连接到网络服务器并接收二进制数据的项目。我的问题是当我从网络服务器下载数据时。如果我发送登录请求或激活某些设置,则没有问题。但是,当我发送下载二进制数据的请求时,它向我抛出一个 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());
I'm working on a project which connect to a web server and receive binary data. My problem is when I'm downloading data from web server. If i send request to login or to activate some setting, there is no problem. But when I send request to download a binary data it's throwing me an OutOfMemoryException
. Here is the code which I'm using :
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;
}
Error from the 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)
Any ideas how to fix that? I tried to increase my buffer's size to 50*1024,but still doesn't help.
EDIT: Error is throws on that line :
buffer = EntityUtils.toByteArray(response.getEntity());
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 Android 上,堆大小有限,当您尝试解码实体时,堆大小会耗尽。我认为您需要使用 http 分块将数据发送到客户端(或者出现问题,EntityUtils 认为它们需要更大的数组。问题是字节数组太大而不是太小。看看这个帖子:
On Android you only have a limited heap size, which gets exhausted while you try to decode your entity. I think you need to use http chunking to send your data to the client (or something goes wrong and the EntityUtils think they need a much bigger array. The problem is a byte array which is to big not to small. Have a look at this posts:
好的,试试这个..
对于
将 InputStream 转换为 String
或
使用 Apache Commons 库 (org.apache.commons.io.IOUtils)。
或者只是写入临时文件,
按照用户 Philipp Reichart 的建议,从 org.apache.http.util 包中写入;
是允许使用字符串转换的
编码格式
的方法。让我知道您仍然遇到
OutOfMemory Error
。谢谢。
Ok, try this..
And for
conversion of InputStream to String
or
use Apache Commons library (org.apache.commons.io.IOUtils).
or just write to temp file,
Ok as per user Philipp Reichart suggested, from package of
org.apache.http.util
;is the method which allow the
encoding format with String Conversion
.and let me know still you get
OutOfMemory Error
.Thanks.