Android http connection refused

Viewed 1776

I created an Android test program with service and activity. In activity I start sticky service. Service make http requests every 10 seconds. If I not exit from activity, all works fine. If I exit, service works sometime, then killed by system and restarted. After restart sometimes http requests works, sometimes gives an error message:

09-28 14:55:18.053 31161-31184/home.xmpp W/System.err: java.net.ConnectException: failed to connect to www.ya.ru/87.250.250.242 (port 80) after 15000ms: isConnected failed: ECONNREFUSED (Connection refused)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.isConnected(IoBridge.java:238)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.connectErrno(IoBridge.java:171)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:122)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.Socket.connect(Socket.java:882)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.Platform.connectSocket(Platform.java:174)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.Connection.connect(Connection.java:152)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:106)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:217)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService.sendPostRequest(MyService.java:160)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService$MyTask.doInBackground(MyService.java:128)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService$MyTask.doInBackground(MyService.java:109)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.lang.Thread.run(Thread.java:818)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err: Caused by: android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.isConnected(IoBridge.java:223)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:  ... 21 more

After the appearance of this error, the following requests will also fail. I tried to start service in another process, tried to start each http request in new IntentService, tried to restart service after this error, but no results. If an error has occurred, then other subsequent requests will also give an error. Only application restart helps. Has anyone encountered such problem? How to make a stable connection? I read a lot of topics, but did not find the right answer.

MyService.java

package home.xmpp;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class MyService extends Service implements ComponentCallbacks2 {
private Boolean disconnectAppeared = false;
static MyService instance;
private Handler mHandler = new Handler();
MyTask mt;
Boolean mtruned = false;


public static MyService getInstance(){
    return instance;
}

@Override
public IBinder onBind(final Intent intent) {
    //throw new UnsupportedOperationException("Not yet implemented");
    return new LocalBinder<MyService>(this);
}

@Override
public void onCreate() {
    super.onCreate();
    instance = this;
    mHandler.postDelayed(timeUpdaterRunnable, 100);
    Log.e("MyService"," created");
}

@Override
public int onStartCommand(final Intent intent, final int flags,
                          final int startId) {
    return Service.START_STICKY;
}

@Override
public boolean onUnbind(final Intent intent) {
    return super.onUnbind(intent);
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.e("MyService"," destroyed");
    mHandler.removeCallbacks(timeUpdaterRunnable);
}

public void onTrimMemory(int level) {
    switch (level) {
        case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: //Release any memory that your app doesn't need to run.
            //the system will begin killing background processes. !!!
            Log.e("Memory level","4");
            break;
        default:
            break;
    }
}

private Runnable timeUpdaterRunnable = new Runnable() {
    public void run() {
        if (mtruned == false) {
            Log.e("Time", " update");
            mt = new MyTask();
            mt.execute();
            mHandler.postDelayed(this, 10000);
        } else {
            cancelTask();
        }
    }
};

private void cancelTask() {
    if (mt == null) return;
    Log.d("MyService", "cancel result: " + mt.cancel(false));
}


    class MyTask extends AsyncTask<String,Void,String> {
        @Override
        protected void onPreExecute() {
            mtruned = true;
            super.onPreExecute();
        }
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.e("http","updated");
            mtruned = false;
        }
        @Override
        protected String doInBackground(String... params) {
            String result = "";
            HashMap<String,String> data = new HashMap<>();
            data.put("data", "data");
                result = sendPostRequest("http://www.ya.ru", data);
            return result;
        }
        @Override
        protected void onCancelled() {
            super.onCancelled();
            mtruned = false;
        }
}

public String sendPostRequest(String requestURL,
                              HashMap<String, String> postDataParams) {
    //Creating a URL
    URL url;

    //StringBuilder object to store the message retrieved from the server
    StringBuilder sb = new StringBuilder();
    try {
        //Initializing Url
        url = new URL(requestURL);

        //Creating an httmlurl connection
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //Configuring connection properties
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);

        //Creating an output stream
        OutputStream os = conn.getOutputStream();

        //Writing parameters to the request
        //We are using a method getPostDataString which is defined below
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.write(getPostDataString(postDataParams));

        writer.flush();
        writer.close();
        os.close();
        int responseCode = conn.getResponseCode();

        if (responseCode == HttpsURLConnection.HTTP_OK) {

            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            sb = new StringBuilder();
            String response;
            //Reading server response
            while ((response = br.readLine()) != null){
                sb.append(response);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}

private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for (Map.Entry<String, String> entry : params.entrySet()) {
        if (first)
            first = false;
        else
            result.append("&");

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

    return result.toString();
}


}

Update 05.10.17 I still not find a solution. I tested this programm on Android 4.1.2. It works fine. On Android 5.1.1 it works about 3 minutes after exiting the activity and then I receive connection refused error. When I return to activity, errors disappears. On Android 6.0.1 similar situation, but the error is slightly different java.net.SocketTimeoutException: failed to connect to /94.130.25.242 (port 80) after 10000ms. I think that the system blocks network activity in services after a while, but never in activities (?).

Update 05.10.17 I noticed that the connection disappears not only after the restart of the service, but also after 2-3 minutes, when exiting activity. When I return to activity, connections are restored. I have made a video Link Update 06.10.17 One Android specialist told me, that this problem appear only in Xiaomi phones. MIUI rejects network connections after some minutes. Only OkHttp helps. I will try it and will make feedback here.

2 Answers

A "connect failed: ECONNREFUSED (Connection refused)" most likely means that there is nothing listening on that port AND that IP address. Possible explanations include:

  • the service has crashed or hasn't been started,
  • your client is trying to connect using the wrong IP address or port, or
  • server access is being blocked by a firewall that is "refusing" on the server/service's behalf. This is pretty unlikely given that normal practice (these days) is for firewalls to "blackhole" all unwanted connection attempts.

It is impossible to use long network connections in background on Xiaomi phones. It's MIUI blocks any network connections after some time. For critical network connections, you can use Firebase Cloud Messaging, which have high priority in Android system. It can initiate necesary background job.

Related