Android - ErrnoException:套接字失败:发出http请求时EMFILE(打开的文件太多)

时间:2015-10-02 19:21:58

标签: java android http

在我的应用程序中,我正在制作http get和http post请求,在关于制作40-50个请求后,我收到以下错误异常。即使在进行调用之后,看起来http连接仍保持打开太多文件。我在底部添加了HTTP Async处理程序及其用法。任何建议都将受到高度赞赏。感谢您抽出时间阅读本文。

10-01 23:08:53.214  30139-30321/com.app W/System.err﹕ org.apache.http.conn.HttpHostConnectException: Connection to http://152.125.228.214:8080 refused
10-01 23:08:53.220  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:188)

10-01 23:08:53.229  30139-30139/com.app E/SharedPreferencesImpl﹕ Couldn't create directory for SharedPreferences file /data/data/com.app/shared_prefs/MY_SHARED_PREF.xml
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at com.app.https.AsyncHttpTask.doInBackground(AsyncHttpTask.java:177)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at com.app.https.AsyncHttpTask.doInBackground(AsyncHttpTask.java:31)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ Caused by: java.net.ConnectException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:186)
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ ... 14 more
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ Caused by: java.net.SocketException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at libcore.io.IoBridge.socket(IoBridge.java:623)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at java.net.Socket.checkOpenAndCreate(Socket.java:687)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at java.net.Socket.connect(Socket.java:847)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:124)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:149)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ ... 14 more
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ Caused by: android.system.ErrnoException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.Posix.socket(Native Method)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.IoBridge.socket(IoBridge.java:608)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ ... 19 more
10-01 23:08:53.242  30139-30139/com.app D/com.app.util.JukeSpotUtils﹕ [ 10-01 23:08:54.556   191:  645 I/AudioFlinger ]
BUFFER TIMEOUT: remove(4101) from active list on thread 0xb5ae5008

以下是发出HTTP请求的代码。

public class AsyncHttpTask extends AsyncTask<String, Void, Response> {

    private HttpHandler httpHandler;

    private TaskCallback taskCallback;

    private HTTPType httpType;

    private String url;

    private String json;

    private NameValuePair[] headers;

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public AsyncHttpTask(HttpHandler httpHandler, TaskCallback taskCallback, HTTPType httpType
        , String url, String json) {
        this.httpHandler = httpHandler;
        this.taskCallback = taskCallback;
        this.httpType = httpType;
        this.url = url;
        this.json = json;
    }

    @Override
    protected void onPreExecute() {
        if (taskCallback != null) {
            taskCallback.onPreExecute();
        }
    }

    @Override
    protected Response doInBackground(String... arg0) {
        InputStream inputStream = null;

        Response responseToReturn = new Response("", 500);
        try {
            Response response = null;
            HttpParams httpParameters = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
            HttpConnectionParams.setSoTimeout(httpParameters, 10000);

            HttpClient httpclient = new DefaultHttpClient(httpParameters);

            HttpResponse httpResponse = httpclient.execute(httpHandler.getHttpRequestMethod());
            inputStream = httpResponse.getEntity().getContent();
            if (inputStream != null) {
                response = new Response(convertInputStreamToString(inputStream), httpResponse.getStatusLine().getStatusCode());
            } else {
                response = new Response("Did not work :(", httpResponse.getStatusLine().getStatusCode());
            }
            responseToReturn = response;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

       return responseToReturn;
    }

    @Override
    protected void onPostExecute(Response response) {
        if (taskCallback != null) {
            taskCallback.onPostExecute();
        }
        httpHandler.onResponse(response);
    }

    private String convertInputStreamToString(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line = "";
        String result = "";
        while ((line = bufferedReader.readLine()) != null) {
            result += line;
        }

        return result;
    }
}

以下是一个Abstract类,我用它来定义我自己的HTTPGet对象和HTTPPost对象的实现。

public abstract class HttpHandler {

    public abstract HttpUriRequest getHttpRequestMethod();

    public abstract void onResponse(Response result);

    public void execute(TaskCallback taskCallback, HTTPType httpType, String url, String json) {
        new AsyncHttpTask(this, taskCallback, httpType, url, json).execute();
    }
}

以下是我在我写的服务中如何使用HttpHandler的代码。

new HttpHandler() {
    @Override
    public HttpUriRequest getHttpRequestMethod() {
        String refreshUrl = JukeSpotUtils.formRequestUrl(context,
                context.getString(R.string.refresh_token_api));
        HttpPost httpPost = new HttpPost(refreshUrl);
        try {
            JSONObject token = new JSONObject();
            token.put("refreshToken", getPreferenceValue(context, context.getString(R.string.refresh_token)));
            httpPost.setHeader("Content-Type", "application/json");

                httpPost.setEntity(new StringEntity(token.toString()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpPost;
    }

    @Override
    public void onResponse(Response response) {
        if (response != null && response.isSuccessful()) {
            try {
                flushOldToken(context, response.getResult());

                Log.d("ACCESS_TOKEN", getPreferenceValue(context, context.getString(R.string.access_token)));

                if (simpleCallback != null) {
                    simpleCallback.callBack();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }        
    }
}.execute(null, HTTPType.POST, true);

1 个答案:

答案 0 :(得分:1)

您的连接未正确关闭或您同时执行了多个httpHandler。您可以尝试使用threadPoolExecutor启动AsyncTask