我尝试了多个 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)
如果你看这个 Android 文档 http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html,它解释了
网络主线程异常:
当应用程序尝试执行某个操作时引发的异常
其主线程上的网络操作。
仅针对 Honeycomb SDK 或
更高。允许针对早期 SDK 版本的应用程序执行以下操作
在他们的主事件循环线程上联网,但它很重
灰心。
因此,根据操作系统版本,可能会强制执行(抛出异常)您不在 UI 线程上发出网络请求的策略。这可以解释为什么你的代码可以在设备上运行,而不是在模拟器上运行(如果它们有不同的 Android 版本)。
You could改变ThreadPolicy
。但作为替代方案,我建议您再次查看 Android 文档中的声明。他们heavily不鼓励在主线程上执行网络操作,我当然同意他们的观点。
所以,与其改变政策使其合法化,您可能会考虑更改您的代码,以便您的getResponse()
方法不在 UI 线程上调用。
通常,您会使用AsyncTask 在后台完成工作 http://developer.android.com/reference/android/os/AsyncTask.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)