HttpURLConnection抛出OutOfMemoryError

时间:2016-09-29 06:28:15

标签: java android apache-httpclient-4.x

我按照developer.android.com中的说明进行网络通话(使用HttpURLConnection)。现在我得到一个内存不足的异常,应用程序正在崩溃。

以下是堆栈跟踪:

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) 

我已经把它包括在我的清单中了:

android:largeHeap="true"

这是我的网络类:

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

并且,我已经确定了&#34; len&#34;是问题并尝试对其进行硬编码,但似乎并不适用于所有场景。

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

请帮帮我。

3 个答案:

答案 0 :(得分:1)

试试这个readIt方法,

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

答案 1 :(得分:0)

您正在尝试

int len =Integer.MAX_VALUE;
char[] buffer = new char[len];
你有那么多记忆吗?

答案 2 :(得分:0)

您正在分配长度为Integer.MAX_LENGTH的char数组,该数组将不适合可用内存。我认为你最好让readIt()看起来像这样:

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");