2012-06-30 15 views
11

Probé varias clases HTTP (HttpURLConnection, HTTPClient y otros), pero que no funcionan en el emulador. ¡Entonces decidí probar eso en mi teléfono y funcionó bien!HTTP no funciona en el emulador de Android

Entonces, ¿cómo puedo solucionar este extraño comportamiento del emulador de Android que HTTP clases no funcionan (mientras que el navegador puede trabajar)? Bloquean una aplicación en absoluto.

Aquí está mi código: registro

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) 
+1

Muestre su código. También explica qué significa "... no funcionan ...". – Squonk

+0

Actualicé la publicación. No funcionan porque solo bloquean mi aplicación. – Uhehesh

+1

Luego publique el registro ... –

Respuesta

20

Si nos fijamos en this Android documentation, explica

NetworkOnMainThreadException:

La excepción que se produce cuando una aplicación intenta realizar una operación de redes en su hilo principal .

Esto solo se aplica a las aplicaciones dirigidas al Honeycomb SDK o al superior. Las aplicaciones que se dirigen a versiones anteriores de SDK pueden hacer redes en sus hilos principales de bucles de eventos, pero se desaconseja fuertemente en .

Por lo tanto, dependiendo de la versión del sistema operativo, puede haber aplicación (excepción) de la política de que no realice solicitudes de red en el hilo de la interfaz de usuario. Esto podría explicar por qué tu código funciona en un dispositivo, y no en un emulador (si tienen diferentes versiones de Android).

Usted podría cambiar el ThreadPolicy. Pero como alternativa, sugiero que vuelvas a mirar la declaración en los documentos de Android. Ellos fuertemente desalentar la realización de operaciones de red en el hilo principal, y ciertamente estoy de acuerdo con ellos.

Así, en lugar de cambiar la política para que sea legal , usted podría considerar la posibilidad de cambiar su código, por lo que su método getResponse() no se llama en el hilo de interfaz de usuario.

Normalmente, utilizaría AsyncTask to do the work in the background.

+0

Nice. Eso es probablemente incluso mejor que esa solución con permitAll(). Pero tengo una pregunta. Estoy haciendo una autorización. ¿Cómo debería hacerlo con AsyncTask? Envío el nombre de usuario y la contraseña usando POST. – Uhehesh

+0

@Uhehesh, solo quería darle otra opción. Como de costumbre, hay más de una forma de resolver un problema :) – Nate

+0

No entiendo.:( – Uhehesh

15

Esto sucede porque intenta realizar la actividad de red en el hilo principal.

que tenían el mismo problema, funcionó durante un tiempo, a continuación, después de algunas semanas de desarrollo, que dejó de funcionar.

La solución que encontré fue la de añadir estas líneas al Método

onCreate() 

:

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

Espero que esto funcione para usted también

EDITAR

Debido a Aumentando el número de upvotes, deseo agregar s omething Esto eliminará el NetworkingOnMainThreadException, SIN EMBARGO, de lejos no es una manera recomendada.

Esta excepción está ahí por una razón. La actividad de red puede llevar tiempo, realizar una red en el hilo principal, que es el mismo hilo responsable de actualizar la interfaz de usuario, congelaría el hilo hasta que se termine la conexión (esto es lo que ocurre en cada hilo, pero cuando se realiza en un hilo, está bien). En Android, si el subproceso UI no está activo durante 5 segundos, se mostrará el cuadro de diálogo Application is not responsive, Do you want to close it?.

Esto es lo que la excepción ha venido a prevenir. Establecer la política, como sugerí, mientras elimina la excepción, es la forma incorrecta de hacer las cosas. Cualquier acción de red debe realizarse en un subproceso separado, ya sea usando AsyncTask o creando Thread nuevo manualmente. AsyncTask son una manera muy fácil y directa de implementar esto, y esto es lo que recomiendo.

Por favor tome esta edición en cuenta al utilizar mi respuesta.

Saludos

+0

Cualquier downvoters, sus opiniones cuentan más que solo un downvote. si crees que esta solución no es buena, dilo. no solo lo marques de esta manera tanto el que nos preguntó como yo podríamos mejorar ... Porque cuando encontré esta respuesta, tenía como 15 votos al alza ... –

+0

Esta es la solución correcta. Votación – EGHDK

+0

Brillante. ¡Me ayudó! Yo votaría pero no tengo suficiente reputación. – Uhehesh

0

deshabilita el modo estricto utilizando el código siguiente:

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

Esto no es recomendable: utilizar la interfaz AsyncTask.

Link of AsyncTask

Link of another reference

Cuestiones relacionadas