Подтвердить что ты не робот

HTTP не работает в эмуляторе Android

Я пробовал несколько классов 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)
4b9b3361

Ответ 1

Если вы посмотрите эту документацию по Android, она объясняет

NetworkOnMainThreadException:

Исключение, возникающее при попытке приложения выполнить сетевой операции в основном потоке.

Это делается только для приложений, ориентированных на SDK Honeycomb или выше. Разрешено использовать приложения, ориентированные на более ранние версии SDK. сети в их основных потоках цикла событий, но это сильно не рекомендуется.

Таким образом, в зависимости от версии ОС может быть принудительное (исключение) политики, что вы не делаете сетевые запросы в потоке пользовательского интерфейса. Это может объяснить, почему ваш код работает на устройстве, а не на эмуляторе (если у них разные версии Android).

Вы можете изменить ThreadPolicy. Но в качестве альтернативы я бы предложил вам снова взглянуть на выражение в документах Android. Они сильно препятствуют выполнению сетевых операций в основном потоке, и я, безусловно, соглашусь с ними.

Итак, вместо того, чтобы изменять политику, чтобы сделать ее законной, вы можете подумать об изменении своего кода, чтобы ваш метод getResponse() не вызывался в потоке пользовательского интерфейса.

Как правило, вы должны использовать AsyncTask для работы в фоновом режиме.

Ответ 2

Это происходит, потому что вы пытаетесь выполнить сетевую активность в основном потоке.

У меня была одна и та же проблема, она работала некоторое время, а затем через несколько недель после ее разработки она перестала работать.

Решение, которое я нашел, это добавить эти строки в

onCreate()

Метод:

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

Надеюсь, это сработает и для вас.

ИЗМЕНИТЬ

Из-за увеличения количества upvotes, я хочу что-то добавить. Это приведет к удалению NetworkingOnMainThreadException, ОДНАКО, это далеко не рекомендуемый способ.

Это исключение существует по какой-то причине. Сетевая активность может занять много времени, и сетевая работа по основному потоку, которая является тем же потоком, который отвечает за обновление пользовательского интерфейса, заморозит поток до тех пор, пока сеть не будет выполнена (это то, что происходит в каждом потоке, но когда оно выполняется на выделенном нить, это нормально). В Android, если UI-поток не активен в течение 5 секунд, он отобразит диалог Application is not responsive, Do you want to close it?.

Это то, что исключение появилось для предотвращения. Настройка политики, как я уже сказал, устраняет исключение, является неправильным способом выполнения действий. Любые сетевые действия должны выполняться в отдельном потоке либо с помощью AsyncTask, либо путем создания нового Thread вручную. AsyncTask - это очень простой и простой способ реализации этого, и это то, что я рекомендую.

Пожалуйста, примите во внимание это изменение при использовании моего ответа.

Приветствия

Ответ 3

Вы отключите строгий режим, используя следующий код:

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

Это не рекомендуется: используйте интерфейс AsyncTask.

Ссылка AsyncTask

Ссылка другой ссылки