2012-01-02 7 views
26

Tengo un problema con mi código y esperaba algo de ayuda. que estaba en primer lugar utilizando este código:DefaultHttpClient to AndroidHttpClient

 new DefaultHttpClient().execute(new HttpGet(linkk)).getEntity().writeTo(
      new FileOutputStream(f)); 

y funciona muy bien en Android 2.3, pero en 4.0 no lo hace. Después de algunas investigaciones, escuché que es mejor usar AndroidHttpClient y de esta manera funcionará en 4.0 y 3.1. El problema es que no sé si modifiqué mi código correctamente y no hay demasiados ejemplos sobre AndroidhttpClient en Internet.

Aquí está mi código que se ajustó:

AndroidHttpClient client = AndroidHttpClient.newInstance("Android"); 
    HttpGet request = new HttpGet(linkk); 
    HttpResponse response = client.execute(request); //here is where the exception is thrown  
    response.getEntity().writeTo(new FileOutputStream(f)); 

Esto es lo que muestra la Logcat:

 01-03 01:32:11.950: W/dalvikvm(17991): threadid=1: thread exiting with uncaught exception (group=0x40a2e1f8) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): FATAL EXCEPTION: main 
    01-03 01:32:11.986: E/AndroidRuntime(17991): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: android.os.NetworkOnMainThreadException 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.access$600(ActivityThread.java:123) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.Handler.dispatchMessage(Handler.java:99) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.Looper.loop(Looper.java:137) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.main(ActivityThread.java:4424) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at java.lang.reflect.Method.invokeNative(Native Method) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at java.lang.reflect.Method.invoke(Method.java:511) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at dalvik.system.NativeStart.main(Native Method) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): Caused by: android.os.NetworkOnMainThreadException 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.lookupHostByName(InetAddress.java:391) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.getAllByName(InetAddress.java:220) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
    01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
+0

Usa la solución recomendada de Android: http://tinyurl.com/88mctoh – wurde

Respuesta

72

StrictMode.ThreadPolicy se introdujo desde API Nivel 9 y la política de subprocesamiento predeterminado se cambió desde API Nivel 11, que en resumen, no permite que se ejecute la operación de red (incluir HttpClient y HttpUrlConnection) en el subproceso de UI. si haces esto, obtienes NetworkOnMainThreadException.

Esta restricción se puede cambiar, usando:

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

Añadir el código anterior en el método de su actividad onCreate().

Además, siempre se recomienda para mover funcionamiento de la red fuera de la rosca UI, por ejemplo, usando AsyncTask.

Espero que esta ayuda.

+9

El objetivo de estas políticas es forzar buenas prácticas y comprobar que su aplicación funciona bien. Desactivar las políticas es una mala idea. Vea la respuesta de Sbossb para el enfoque correcto. – rgardler

+4

@rgardler, lea la respuesta detenidamente: ** siempre se recomienda mover el funcionamiento de la red fuera de la secuencia de la interfaz de usuario, por ejemplo, utilizando AsyncTask.** La política de subprocesos se modificó sin resaltar y muchos desarrolladores no están al tanto, vale la pena señalar el motivo exacto por el que el mismo código funciona en GingerBread pero no en HoneyComb. También se recomienda que AsyncTask sea recomendado pero definitivamente no el único correcto. – yorkw

+2

@yorkw Ugh ... ¿por qué pondría esto como la respuesta?!? A los principiantes que buscan una solución rápida no les va a importar ... solo copian y pegan el código en su proyecto y será su culpa cuando otra aplicación de mierda se publique en Android Market. –

32

Utilice un AsyncTask de modo que la solicitud de red no bloquea el hilo de interfaz de usuario. El NetworkOnMainThreadException se introdujo desde la versión 11 de la API, que es la razón por la que solo aparece 3.0 y más.

private class NetworkTask extends AsyncTask<String, Void, HttpResponse> { 
    @Override 
    protected HttpResponse doInBackground(String... params) { 
     String link = params[0]; 
     HttpGet request = new HttpGet(link); 
     AndroidHttpClient client = AndroidHttpClient.newInstance("Android"); 
     try { 
      return client.execute(request); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return null; 
     } finally { 
     client.close(); 
    } 
    } 

    @Override 
    protected void onPostExecute(HttpResponse result) { 
     //Do something with result 
     if (result != null) 
      result.getEntity().writeTo(new FileOutputStream(f)); 
    } 
} 

Llamar a este hilo simple de hacer esto.

new NetworkTask().execute(linkk); 

Tome un vistazo a this article escrita en el sitio de desarrolladores de Android. Explica con más detalle cómo escribir su aplicación para manejar los hilos.

+0

He intentado esto y me da un error que no puedo resolver. Esto es lo que muestra el logcat: 01-03 15: 01: 46.508: E/AndroidRuntime (23161): java.lang.RuntimeException: no se puede iniciar la actividad ComponentInfo {com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: java.lang.IndexOutOfBoundsException: el índice 0 no es válido, el tamaño es 0 01-03 15: 36: 44.121: E/AndroidRuntime (24957): \t en android.app.ActivityThread.performLaunchActivity (ActivityThread.java:1956) – Lara

+0

He comentado el String link = params [0]; y también he rodeado client.execute (solicitud); con try/catch – Lara

Cuestiones relacionadas