我正在尝试使用Android HttpClient阅读相当大的响应主体(视频数据> 5 MB)。我已经使用AsyncTask方法在后台执行网络任务。代码在读取调用时卡住,并且OutofMemoryError超时。
我还尝试过defauly EntityUtils方法,该方法也返回OutofMemoryError,这是合理的,因为这是要在内存中读取的相当大量的数据。
有一个小的粗略检查,以检查它是否是二进制数据以防万一。
关于为什么读取阻塞的任何想法?
protected HttpResponse doInBackground(String... params) {
String link = params[0];
HttpResponse response = null;
HttpGet request = new HttpGet(link);
//Just in case we need proxy
if (isCancelled())
{
Log.d(LOGTAG, "Background task cancelled");
}
//Start android client for sending first request
Log.d(LOGTAG, "Proxy is disabled");
client = AndroidHttpClient.newInstance("Android");
try
{
response = client.execute(request);
if(response != null)
{
try
{
//HttpEntity entity = response.getEntity();
Log.d(LOGTAG,"Parsing Response");
String line = "";
// Wrap a BufferedReader around the InputStream
InputStream responseStream = response.getEntity().getContent();
//This causes OutofMemoryError
//responseBody = EntityUtils.toString(getResponseEntity);
int read=0;
byte[] bytes = new byte[12288];
OutputStream output = null;
String filename = searchContentUrl.replace('/', '_');
File outfile = new File(AppMainActivity.dataDir, filename);
output = new BufferedOutputStream(new FileOutputStream(outfile));
int firstChunkCheck = 0;
while((read = responseStream.read(bytes))!= -1)
{
CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
if(binaryData == 0)
{
if (firstChunkCheck == 0) //Crude check for binary data
{
if(encoder.canEncode(new String(bytes)))
Log.d(LOGTAG,"Got normal Data");
binaryData = 0;
firstChunkCheck = 1;
}
responseBody += new String(bytes);
}
else
{
//Toast.makeText(getApplicationContext(), "Downloading file ", Toast.LENGTH_SHORT).show();
binaryData = 1;
Log.d(LOGTAG, "Writing binary file...");
try
{
output.write(bytes);
}
catch(FileNotFoundException ex)
{
Log.d(LOGTAG, "FileNotFoundException");
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
if(output != null)
output.close();
Log.d(LOGTAG,"Read Response");
return response;
}
catch (ParseException e)
{
Log.d(LOGTAG,"IOException while getting Response");
e.printStackTrace();
return null;
}
catch (UnsupportedEncodingException e)
{
Log.d(LOGTAG,"UnsupportedEncodingException while decoding uri");
e.printStackTrace();
return null;
}
catch (IOException e)
{
Log.d(LOGTAG,"IOException while decoding uri");
e.printStackTrace();
return null;
}
}
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
finally
{
//client.close();
}
return response;
}
答案 0 :(得分:0)
您正在尝试在编写数据时对数据进行编码。而是将原始数据写入文件,然后在读取时对其进行编码。这允许您使用InputStreamReader
作为特定字符集,它会为您处理所有细节。这只能在所有数据都可用时完成,正如您可能已经意识到的那样。
此外,行responseBody += new String(bytes);
看起来有点奇怪。