简体   繁体   English

Android:读取HTTP响应时读取块

[英]Android : Read blocks while reading HTTP response

I am trying to read a fairly large response body (video data > 5 MB) using Android HttpClient. 我正在尝试使用Android HttpClient读取相当大的响应正文(视频数据> 5 MB)。 I have used the AsyncTask method to execute the network task in background. 我已经使用AsyncTask方法在后台执行网络任务。 The code gets stuck at the read call and times out with OutofMemoryError. 代码卡在读取调用中,并因OutofMemoryError超时而停滞。

I have also tried the defauly EntityUtils method which also returns the OutofMemoryError which is justifiable as this is a fairly large amount of data to be read in memory. 我还尝试了defauly EntityUtils方法,该方法还返回OutofMemoryError,这是合理的,因为这是要在内存中读取的相当大量的数据。

There is a minor crude check for checking if it is a binary data just in case. 有一个小的粗略检查,以检查它是否是二进制数据,以防万一。

Any ideas as to why the read is blocking ?? 关于为何读取受阻的任何想法?

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;
    }

You are trying to encode the data as you write it. 您正在尝试在编写数据时对其进行编码。 Instead, write the raw data to a file, and then encode it as you read it. 而是将原始数据写入文件,然后在读取时对其进行编码。 This allows you to use an InputStreamReader for your specific character set, which takes care of all the details for you. 这使您可以将InputStreamReader用于特定的字符集,从而为您处理所有详细信息。 This can only be done when all the data is available, as you have probably realised. 正如您可能已经意识到的那样,只有在所有数据都可用时才能完成此操作。

In addition, the line responseBody += new String(bytes); 另外,行responseBody += new String(bytes); looks a bit odd. 看起来有点奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM