我尝试了多个HTTP类(HttpURLConnection
,HTTPClient
和其他类),但它们在模拟器中不起作用。然后我决定在我的手机上测试它并且效果很好!
那么如何修复Android模拟器的这种奇怪的行为,即HTTP类不起作用(浏览器可以工作)?他们崩溃了一个应用程序。
这是我的代码:
public static SimpleXML getResponse(String action, Map<String, String> params) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(action);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(params.size());
for(Map.Entry<String, String> heh : params.entrySet())
nameValuePairs.add(new BasicNameValuePair(heh.getKey(), heh.getValue()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
return SimpleXML.loadXml(response.getEntity().getContent());
} catch (ClientProtocolException e) {
return null;
} catch (IOException e) {
return null;
}
}
LogCat日志:
06-30 22:07:28.972: E/AndroidRuntime(682): FATAL EXCEPTION: main
06-30 22:07:28.972: E/AndroidRuntime(682): android.os.NetworkOnMainThreadException
06-30 22:07:28.972: E/AndroidRuntime(682): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
06-30 22:07:28.972: E/AndroidRuntime(682): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
06-30 22:07:28.972: E/AndroidRuntime(682): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
06-30 22:07:28.972: E/AndroidRuntime(682): at java.net.InetAddress.getAllByName(InetAddress.java:214)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-30 22:07:28.972: E/AndroidRuntime(682): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
06-30 22:07:28.972: E/AndroidRuntime(682): at net.ekvium.air.API.getResponse(API.java:98)
06-30 22:07:28.972: E/AndroidRuntime(682): at net.ekvium.air.MainActivity$1.onClick(MainActivity.java:62)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.view.View.performClick(View.java:4084)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.view.View$PerformClick.run(View.java:16966)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.os.Handler.handleCallback(Handler.java:615)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.os.Handler.dispatchMessage(Handler.java:92)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.os.Looper.loop(Looper.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682): at android.app.ActivityThread.main(ActivityThread.java:4745)
06-30 22:07:28.972: E/AndroidRuntime(682): at java.lang.reflect.Method.invokeNative(Native Method)
06-30 22:07:28.972: E/AndroidRuntime(682): at java.lang.reflect.Method.invoke(Method.java:511)
06-30 22:07:28.972: E/AndroidRuntime(682): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
06-30 22:07:28.972: E/AndroidRuntime(682): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
06-30 22:07:28.972: E/AndroidRuntime(682): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:20)
如果你看一下this Android documentation,就会解释
<强> NetworkOnMainThreadException:强>
应用程序尝试执行时抛出的异常 在其主线程上进行网络操作。
这仅适用于针对Honeycomb SDK或。的应用程序 更高。允许使用早期SDK版本的应用程序 他们的主要事件循环线程上的网络,但它是很重要的 气馁。
因此,根据操作系统版本,可能会强制执行(异常抛出)您未在UI线程上发出网络请求的策略。这可以解释为什么您的代码可以在设备上运行,而不是在模拟器上运行(如果它们具有不同的Android版本)。
您可以更改ThreadPolicy
。但作为替代方案,我建议您再次查看Android文档中的声明。他们严重不鼓励在主线程上执行网络操作,我当然同意这些操作。
因此,您可以考虑更改代码,而不是将策略更改为使其合法,以便不在UI线程上调用getResponse()
方法。
答案 1 :(得分:15)
这是因为您尝试在主线程上执行网络活动。
我有同样的问题,它工作了一段时间,然后经过几周的开发,它停止了工作。
我找到的解决方案是将这些行添加到
onCreate()
方法:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
希望这也适合你
修改强>
由于赞成票数量增加,我希望补充一些内容。
这将删除NetworkingOnMainThreadException
,但是,这是目前为止不推荐的方式。
这个例外是有原因的。网络活动可能需要一些时间,在主线程上执行网络,这是负责更新UI的相同线程,会冻结线程直到网络完成(这是在每个线程上发生的事情,但是当它在专用线程上执行时线程,没关系)。在Android中,如果UI线程在5秒内未处于活动状态,则会显示Application is not responsive, Do you want to close it?
对话框。
这是防止异常的原因。像我建议的那样设置策略,同时删除异常,这是错误的做事方式。
任何网络操作都应该在单独的线程上完成,方法是使用AsyncTask
或手动创建新的Thread
。 AsyncTask
是一种非常简单直接的实现方式,这就是我的建议。
请在使用我的答案时考虑此编辑。
干杯
答案 2 :(得分:0)
使用以下代码禁用严格模式:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
不建议这样做:使用AsyncTask
界面。