3

I have an AsyncTask, connecting to my server.

When I run it from Activity - everything works good.

But when it is started from BroadcastReceiver inside onReceive() and application is in background - it always throws Exception:
Unable to resolve host *myHostHere* No address associated with hostname

When application is in foreground - everything is also good.

Where did I make mistake?

1. onReceive() code:

@Override
    public void onReceive(final Context context, Intent intent) {
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    MonitoringHelper.getInstance(context).sendData();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

2. In sendData() I run AsyncTask with:

new SendMessageAsync(context, this).execute(json);

3. doInBackground():

@Override
    protected Boolean doInBackground(String ... params) {
        HttpPost httpPost = new HttpPost("http://" + serverAddress.replace("http://", "") + "/mobile/message");
        httpPost.setHeader("Content-type", "application/json");

        HttpClient client = new DefaultHttpClient();
        HttpResponse response;
        StringBuilder stringBuilder = new StringBuilder();

        try {
            httpPost.setEntity(new StringEntity(params[0]));
            response = client.execute(httpPost);
            HttpEntity entity = response.getEntity();
            InputStream stream = entity.getContent();
            int b;
            while ((b = stream.read()) != -1) {
                stringBuilder.append((char) b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

4. Logcat:

09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err: java.net.UnknownHostException: Unable to resolve host "myHostHere": No address associated with hostname
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.net.InetAddress.lookupHostByName(InetAddress.java:457)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.net.InetAddress.getAllByName(InetAddress.java:215)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:142)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:369)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at com.hys.behappy.utils.SendMessageAsync.doInBackground(SendMessageAsync.java:65)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at com.hys.behappy.utils.SendMessageAsync.doInBackground(SendMessageAsync.java:27)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.lang.Thread.run(Thread.java:818)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at libcore.io.Posix.android_getaddrinfo(Native Method)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
09-14 10:58:05.684 16024-25007/com.hys.behappy W/System.err:     at java.net.InetAddress.lookupHostByName(InetAddress.java:438)

PS. Permissions in manifest

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

PPS. Moved AsyncTask to IntentService.
Result is the same.

PPPS. Seems to be great device-specific issue - it doesn't work on Xiaomi Redmi Note 3 Pro, but works like charm on LGE Nexus.
Any advices?

Goltsev Eugene
  • 3,325
  • 6
  • 25
  • 48

2 Answers2

2

A BroadcastReceiver has a very short lifetime - just the onReceive() method. After that it will be destroyed (unless it was registered by an Activity.) Even though you are creating a secondary thread to then kick off an AsyncTask via some static instance class, this will have no effect on your app's lifecycle or power management and is generally not a good idea. It would actually be possible for your app to be killed if the only component is the BroadcastReceiver, triggered by an Intent which was registered in the manifest.

When the device is idle (screen off) it will try to go into a lower power state. With Marshmallow on, it can also go into Doze Mode before that, which causes a partial dropout of services, such as networking. On pre-Marshmallow devices, you could use a WakefulBroadcastReceiver to start a service and take a wakelock. Then, in your service do some work and release the wakelock when done. However, starting with Marshmallow, Doze mode affects this and causes all wakelocks to be ignored.

Also, you may want to have a look at how your AsyncTask is being created and started; there are restrictions where it must be created and started on the main thread:

Threading rules

There are a few threading rules that must be followed for this class to work properly:

  • The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.

  • The task instance must be created on the UI thread.

  • execute(Params...) must be invoked on the UI thread.

...

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • That's interesting that it is device specific. You may want to try using `HttpURLConnection` instead of `HttpClient`. There are some size and performance issues with `HttpClient` and it's only considered a good choice if you are supporting devices running Froyo or earlier. It's possibly the device manufacturers did something to the apache http client code which breaks. – Larry Schiefer Sep 14 '16 at 13:51
2

I'm not sure if this is still active but I've had same problem and managed to find solution.

Xiaomi by default restricts all background activites when possible and you can actually disable that for all apps or just for some specific apps.

What restricting actually does is that it restricts internet connection for your app when it's backgrounded so you get UnknownHostException because it actually has no internet connection.

So, to fix this just go to Settings -> "Battery & performance" -> "Manage apps battery usage" and turn it off completely for all apps or click on "Choose apps" and turn it off only for your app.

Hope it helps!

  • Unfortunately I'm not able to check it, as it was a long-long ago ) But anyway you are right about Xiaomi, I also discovered it. So I think it really might be a reason! – Goltsev Eugene Aug 24 '17 at 15:15