0

I am making a network call as instructed in developer.android.com (by using HttpURLConnection). Now I am getting a out of memory exception and app is getting crashed.

The following is the stack trace:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.example.app, PID: 19869
    java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:318)
    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:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)
    Caused by: java.lang.OutOfMemoryError: Failed to allocate a 4294967306 byte allocation with 4056144 free bytes and 370MB until OOM
    at com.example.app.webservices.HttpConnectionClass.readIt(HttpConnectionClass.java:158)
    at com.example.app.webservices.HttpConnectionClass.downloadUrl(HttpConnectionClass.java:123)
    at com.example.app.webservices.HttpConnectionClass.access$100(HttpConnectionClass.java:28)
    at com.example.app.webservices.HttpConnectionClass$DownloadWebpageTask.doInBackground(HttpConnectionClass.java:52)
    at com.example.app.webservices.HttpConnectionClass$DownloadWebpageTask.doInBackground(HttpConnectionClass.java:46)
    at android.os.AsyncTask$2.call(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 

I've already included this in my manifest :

android:largeHeap="true"

This is my Networkclass:

public class HttpConnectionClass {

    public static Activity context;

    List json;
    static boolean dialogIsShowing = true;
    public String url;
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    public void getPostResponse_WithAsyn(Activity context, String url, List json, String message) {
        this.params = json;
        this.url= url;
        this.json = json;
        Log.v("TAG","PARAMS::"+json.toString());
        //add all the default parameters here
        new DownloadWebpageTask().execute(url);
    }

    private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            // params comes from the execute() call: params[0] is the url.
            try {
                return downloadUrl(urls[0]);
            } catch (IOException e) {
                e.printStackTrace();
                return "Unable to retrieve web page. URL may be invalid.";
            }
        }
        // onPostExecute displays the results of the AsyncTask.
        @Override
        protected void onPostExecute(String result) {

            GetHttpPostResponse.myJsonResponse = result;

            /*int maxLogSize = 1000;
            for(int i = 0; i <= result.length() / maxLogSize; i++) {
                int start = i * maxLogSize;
                int end = (i+1) * maxLogSize;
                end = end > result.length() ? result.length() : end;
                Log.v("TAG_result", result.substring(start, end));
            }
            */
             Log.v("Connection class","Response::"+result);
        }
    }

    private String downloadUrl(String myurl) throws IOException {
        InputStream is = null;
        // Only display the first 500 characters of the retrieved
        // web page content.
        int len =Integer.MAX_VALUE;

        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            Log.v("TAG","CONNECTING URL::"+myurl);
            conn.setReadTimeout(10000 /* milliseconds */);
            conn.setConnectTimeout(15000 /* milliseconds */);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);

            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("key1", ""));
            params.add(new BasicNameValuePair("key2", ""));

            Log.v("TAG","PARAMETERS::"+params.toString());
            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            writer.write(getQuery(params));
            writer.flush();
            writer.close();
            os.close();

            // Starts the query
            conn.connect();

            int response = conn.getResponseCode();
            String res_data = conn.getResponseMessage();
            Log.d("TAG", "The response is: " + res_data);
            is = conn.getInputStream();

            // Convert the InputStream into a string
            String contentAsString = readIt(is, len);
            return contentAsString;

            // Makes sure that the InputStream is closed after the app is
            // finished using it.
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    private String getQuery(List<NameValuePair> params) throws IOException,UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;

        for (NameValuePair pair : params) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
        }

        return result.toString();
    }
    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
        Reader reader = null;
        reader = new InputStreamReader(stream, "UTF-8");
        char[] buffer = new char[len];
        reader.read(buffer);
        return new String(buffer);
    }
}

And,I've Identified that "len" is the problem and tried to hardcode it but doesn't seem to work in all scenarios.

{"ResponseCode":"-1000","ResponseDesc":"Invalid user type."}�

Please help me out.

3 Answers 3

1

Try this readIt method,

public String readIt(InputStream stream) throws IOException, UnsupportedEncodingException {
    StringBuffer sb = new StringBuffer();
    BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
    String line;
    while ((line = br.readLine()) != null){
      sb.append(line);
    }
    br.close();
    return sb.toString();
}
Sign up to request clarification or add additional context in comments.

Comments

0

You are trying to do

int len =Integer.MAX_VALUE;
char[] buffer = new char[len];

do you have that much memory?

5 Comments

thank you for quick reply.Yes,the data I'm getting from server is huge
But you are on an Android and even if you were not I am sure that the default heap size would not be set for this much memory
read the error - Failed to allocate a 4294967306 byte allocation with 4056144 free bytes
By having {"ResponseCode":"-1000","ResponseDesc":"Invalid user type."} it means that you are having an error anyway. Contact the service provider and find out what is required
No,I just posted information that I'm getting additional data along with my json in another scenarios.
0

You are allocating char array of length Integer.MAX_LENGTH, which will not fit in the available memory. I think you would be better of to have readIt() look something like this:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int l;
while ((l = stream.read(buffer)) != -1) {
    baos.write(buffer, 0, l);
}
return baos.toString("UTF-8");

3 Comments

Hello Thank you for quick reply,yes i've tried it but I am getting question marks with my response which is making parsing difficult. Like this :{"ResponseCode":"-1000","ResponseDesc":"Invalid user type."}�������������������������������������������������������������
Is the response encoded using something other than UTF-8?
No,only UTF-8 is being used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.