Android 来自服务的 AsyncTask(从接收器启动)无法解析主机
Android AsyncTask from Service (started from receiver) unable to resolve host
我有一个 AsyncTask
,连接到我的服务器。
当我从 Activity
运行 时 - 一切正常。
但是当它从 onReceive()
中的 BroadcastReceiver
启动并且应用程序处于后台时 - 它总是抛出 Exception
:
Unable to resolve host *myHostHere* No address associated with hostname
当应用程序在前台时 - 一切都很好。
我哪里弄错了?
1. onReceive()
代码:
@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. 在 sendData()
I 运行 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.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.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. 清单中的权限
<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. 将 AsyncTask 移至 IntentService。
结果相同。
PPPS. 似乎是特定于设备的重大问题 - 它不适用于小米 Redmi Note 3 Pro,但在 LGE Nexus 上效果很好.
有什么建议吗?
A BroadcastReceiver
的生命周期非常短 - 只有 onReceive()
方法。之后它将被销毁(除非它是由 Activity
注册的。)即使您正在创建一个辅助线程然后通过一些静态实例 class 启动 AsyncTask
,这也会对您的应用程序的生命周期或电源管理没有影响,通常不是一个好主意。如果唯一的组件是 BroadcastReceiver
,由在清单中注册的 Intent
触发,您的应用程序实际上有可能被终止。
当设备空闲(屏幕关闭)时,它会尝试进入低功耗状态。启用 Marshmallow 后,它还可以在此之前进入 Doze Mode,这会导致部分服务丢失,例如网络。在 Marshmallow 之前的设备上,您可以使用 WakefulBroadcastReceiver
来启动服务并获取唤醒锁。然后,在您的服务中做一些工作并在完成后释放唤醒锁。但是,从 Marshmallow 开始,Doze 模式会影响这一点并导致所有唤醒锁被忽略。
另外,您可能想看看您的 AsyncTask
是如何创建和启动的;在必须在主线程上创建和启动它的地方有一些限制:
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.
...
我不确定这是否仍然有效,但我遇到了同样的问题并设法找到了解决方案。
默认情况下,小米会尽可能限制所有后台活动,您实际上可以为所有应用程序或仅为某些特定应用程序禁用它。
限制实际上做的是它限制你的应用程序在后台时的互联网连接,所以你得到 UnknownHostException 因为它实际上没有互联网连接。
因此,要解决此问题,只需转到设置 -> "Battery & performance" -> "Manage apps battery usage" 并为所有应用程序完全关闭它,或者单击 "Choose apps" 并仅将其关闭你的应用程序。
希望对您有所帮助!
我有一个 AsyncTask
,连接到我的服务器。
当我从 Activity
运行 时 - 一切正常。
但是当它从 onReceive()
中的 BroadcastReceiver
启动并且应用程序处于后台时 - 它总是抛出 Exception
:
Unable to resolve host *myHostHere* No address associated with hostname
当应用程序在前台时 - 一切都很好。
我哪里弄错了?
1. onReceive()
代码:
@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. 在 sendData()
I 运行 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.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.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. 清单中的权限
<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. 将 AsyncTask 移至 IntentService。
结果相同。
PPPS. 似乎是特定于设备的重大问题 - 它不适用于小米 Redmi Note 3 Pro,但在 LGE Nexus 上效果很好.
有什么建议吗?
A BroadcastReceiver
的生命周期非常短 - 只有 onReceive()
方法。之后它将被销毁(除非它是由 Activity
注册的。)即使您正在创建一个辅助线程然后通过一些静态实例 class 启动 AsyncTask
,这也会对您的应用程序的生命周期或电源管理没有影响,通常不是一个好主意。如果唯一的组件是 BroadcastReceiver
,由在清单中注册的 Intent
触发,您的应用程序实际上有可能被终止。
当设备空闲(屏幕关闭)时,它会尝试进入低功耗状态。启用 Marshmallow 后,它还可以在此之前进入 Doze Mode,这会导致部分服务丢失,例如网络。在 Marshmallow 之前的设备上,您可以使用 WakefulBroadcastReceiver
来启动服务并获取唤醒锁。然后,在您的服务中做一些工作并在完成后释放唤醒锁。但是,从 Marshmallow 开始,Doze 模式会影响这一点并导致所有唤醒锁被忽略。
另外,您可能想看看您的 AsyncTask
是如何创建和启动的;在必须在主线程上创建和启动它的地方有一些限制:
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.
...
我不确定这是否仍然有效,但我遇到了同样的问题并设法找到了解决方案。
默认情况下,小米会尽可能限制所有后台活动,您实际上可以为所有应用程序或仅为某些特定应用程序禁用它。
限制实际上做的是它限制你的应用程序在后台时的互联网连接,所以你得到 UnknownHostException 因为它实际上没有互联网连接。
因此,要解决此问题,只需转到设置 -> "Battery & performance" -> "Manage apps battery usage" 并为所有应用程序完全关闭它,或者单击 "Choose apps" 并仅将其关闭你的应用程序。
希望对您有所帮助!