0

Android HttpClient を使用して、かなり大きな応答本文 (ビデオ データ > 5 MB) を読み込もうとしています。AsyncTask メソッドを使用して、バックグラウンドでネットワーク タスクを実行しました。コードは読み取り呼び出しでスタックし、OutofMemoryError でタイムアウトします。

また、これはメモリに読み込まれるかなり大量のデータであるため、正当な OutofMemoryError を返すデフォルトの EntityUtils メソッドも試しました。

念のため、バイナリデータであるかどうかを確認するためのマイナーな大雑把なチェックがあります。

読み取りがブロックされている理由についてのアイデアはありますか??

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

1 に答える 1

0

書き込み時にデータをエンコードしようとしています。代わりに、生データをファイルに書き込み、読み取り時にエンコードします。これによりInputStreamReader、特定の文字セットに を使用して、すべての詳細を処理できます。おそらくお気づきのように、これはすべてのデータが利用可能な場合にのみ実行できます。

さらに、線responseBody += new String(bytes);が少し奇妙に見えます。

于 2013-09-10T08:10:53.110 に答える