添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Android - ErrnoException: socket failed:在发出http请求时,EMFILE(有太多的开放文件)。

2 人关注

在我的应用程序中,我正在发出http get和http post请求,在发出大约40-50个请求后,我得到了以下错误异常。看起来,即使是在调用之后,http连接也保持了太多的文件开放。我在底部添加了HTTP异步处理程序及其使用方法。如果有任何建议,我们将非常感激。谢谢你花时间阅读这个问题。

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;

下面是一个抽象类,我用它来定义我自己的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 个评论
你能不能也分享一下对AsyncHttpTask的调用?
java
android
http
anonymous123
anonymous123
发布于 2015-10-03
2 个回答
Karan
Karan
发布于 2021-08-31
已采纳
0 人赞同

要么你的连接没有正确关闭,要么你同时执行了许多httpHandler。你可以尝试使用threadPoolExecutor来启动AsyncTask

Joshua Pinter
Joshua Pinter
发布于 2021-08-31
0 人赞同

Close your responses with response.close() .

我们在做多线程联网时遇到了这个问题,期间遇到了很多 400 的响应(故意的)。

修复它的方法是确保 response 在遇到不成功的请求时被关闭,具体做法是。