有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java HttpURLConnection抛出OutOfMemoryError

我正在按照开发者的指示打网络电话。安卓com(通过使用HttpURLConnection)。现在我遇到内存不足异常,应用程序崩溃

以下是堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.example.app, PID: 19869
    java.lang.RuntimeException: An error occurred while executing doInBackground()
    at 安卓.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 安卓.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 安卓.os.AsyncTask$2.call(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at 安卓.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) 

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

安卓: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);
    }
}

而且,我已经确定“len”是问题所在,并尝试对其进行硬编码,但似乎并不适用于所有场景

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

请帮帮我


共 (3) 个答案

  1. # 1 楼答案

    您正在分配长度为整数的字符数组。最大长度,无法放入可用内存。我认为你最好让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");
    
  2. # 2 楼答案

    你在努力做什么

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

    你有那么大的记忆力吗

  3. # 3 楼答案

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