致命异常:AsyncTask#2 java.lang.RuntimeException:执行doInBackground()时发生错误。引起:java.lang.OutOfMemoryError

时间:2016-05-17 08:15:16

标签: java android android-asynctask out-of-memory

这是我在NetworkManager类中的doInBackground()

@Override
protected String doInBackground(Void...pParams) {

    try {
        // check if connected to Internet
        if(vIsConnectionAvailable()) {
            // create the URL with the target URL specified
            URL url = new URL(vTargetURL);
            // create a HTTP connection to the URL specified
            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            // set the timeout for the request
            urlConnection.setReadTimeout(REQUEST_TIMEOUT);
            urlConnection.setConnectTimeout(REQUEST_TIMEOUT);
            //add request header
            urlConnection.setRequestMethod("POST");
            // set the HTTP headers for the request.
            urlConnection.setRequestProperty("Content-Length", String.valueOf(vRequestXML.length()));
            for (HashMap.Entry<String, String> entry : vHttpHeaders.entrySet()) {
                urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
            }
            // send the request
            DataOutputStream dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());
            dataOutputStream.writeBytes(vRequestXML);
            dataOutputStream.flush();
            dataOutputStream.close();

            // read the response
            //int bufferSize = 1024 * 100; // 10KB. // Integer.MAX_VALUE - 1000; //
            //int fileSize = 100 * 1024; // 100 * 1024 * 1024 = 100MB.

            //BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String inrtermediateLine;
            StringBuffer responseBuffer = new StringBuffer();
            while ((inrtermediateLine = bufferedReader.readLine()) != null) {
                responseBuffer.append(inrtermediateLine);
            }
            // close the bufferedReader
            bufferedReader.close();
            return responseBuffer.toString();
        }
        else {}
 }

   catch (SocketTimeoutException exception) {

        vErrorCode = -2; //Request Timed out
        return null;
    }

    catch (IOException exception) {
        vErrorCode = -3; //Not able to connect to the target server
        return null;
    }
}

对于xml请求我得到了非常大的响应,并且对于小响应它工作正常...请帮我解决这个问题!我可以使用xml文件来存储响应吗?如果那么请帮助如何为此响应创建xml文件..

这是我的请求格式...  public void vGetPnLData()     {

    String getReportXML = "<ENVELOPE>.....";
    HashMap<String, String> httpHeaders = new HashMap<String, String>();

    // set the headers
    httpHeaders.put("ID", MainActivity.vReportName);
    httpHeaders.put("SOURCE", "EA");
    httpHeaders.put("TARGET", "TALLY");
    httpHeaders.put("Content-Type", "text/xml; charset=utf-8");
    httpHeaders.put("Accept-Encoding", "identity");
    httpHeaders.put("TARGETACCOUNTINTERNALID", MainActivity.vAccountInternalId);
    httpHeaders.put("TARGETCOMPANYNAME", MainActivity.vConnectedCompany);

    // create an object NetwrokManager class. This is an AsyncTask which handles everything related to sending the HTTP requests
    NetworkManager networkMgrObj = new NetworkManager(MainActivity.vReportName, MainActivity.vTrbUrl, getReportXML, httpHeaders);
    // execute the AyncTask
    networkMgrObj.execute();
}

public static void getPLDataResponseCallback(String pResponse) {

    // parse the response to get the report data
    String pLSheetData[][] = XMLParser.getPLBackupReportData(pResponse);

    if (pLSheetData == null)
    {
        // show the error message
        //Error = "No Data found. Please check report in Tally";
    }
    else
    {....}}

这给了我以下错误....

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.visionsolutionsindia.visiontallyapp, PID: 5335
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)                                                                                           
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 57283554 byte allocation with 16777216 free bytes and 51MB until OOM
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:146)                                                                                           
at java.lang.StringBuffer.append(StringBuffer.java:219)                                                                                           
at com.visionsolutionsindia.visiontallyapp.NetworkManager.doInBackground(NetworkManager.java:103)
at com.visionsolutionsindia.visiontallyapp.NetworkManager.doInBackground(NetworkManager.java:39)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)                                                                                            
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818) 

1 个答案:

答案 0 :(得分:0)

尝试将传入的响应分成一组 responseBuffer -packets并处理数据包的传入行:

// Set an upper limit for responsebuffer size
static const int BLOCKSIZE = 1024;
while ((inrtermediateLine = bufferedReader.readLine()) != null) {
    responseBuffer.append(inrtermediateLine);
    if ( responseBuffer.lenght() > BLOCKSIZE ) {
        // implement your response ahndling here!
        handleResponse(responseBuffer);
        responseBuffer.delete(0, responseBuffer.length());
    }
}

在您的代码中,您将增加响应缓冲区,直到没有更多内存要分配。特别是在嵌入式设备上,这是处理大数据blob的危险策略。