HTTP在Android模拟器中不起作用

时间:2012-06-30 21:16:13

标签: android http

我尝试了多个HTTP类(HttpURLConnectionHTTPClient和其他类),但它们在模拟器中不起作用。然后我决定在我的手机上测试它并且效果很好!

那么如何修复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)

3 个答案:

答案 0 :(得分:20)

如果你看一下this Android documentation,就会解释

<强> NetworkOnMainThreadException:

  

应用程序尝试执行时抛出的异常   在其主线程上进行网络操作。

     

这仅适用于针对Honeycomb SDK或。的应用程序   更高。允许使用早期SDK版本的应用程序   他们的主要事件循环线程上的网络,但它是很重要的   气馁。

因此,根据操作系统版本,可能会强制执行(异常抛出)您未在UI线程上发出网络请求的策略。这可以解释为什么您的代码可以在设备上运行,而不是在模拟器上运行(如果它们具有不同的Android版本)。

可以更改ThreadPolicy。但作为替代方案,我建议您再次查看Android文档中的声明。他们严重不鼓励在主线程上执行网络操作,我当然同意这些操作。

因此,您可以考虑更改代码,而不是将策略更改为使其合法,以便不在UI线程上调用getResponse()方法。

通常,您会使用AsyncTask to do the work in the background

答案 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或手动创建新的ThreadAsyncTask是一种非常简单直接的实现方式,这就是我的建议。

请在使用我的答案时考虑此编辑。

干杯

答案 2 :(得分:0)

使用以下代码禁用严格模式:

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = 
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

不建议这样做:使用AsyncTask界面。

Link of AsyncTask

Link of another reference