web-dev-qa-db-fra.com

DefaultHttpClient à AndroidHttpClient

J'ai un problème avec mon code et j'espérais de l'aide. J'utilisais d'abord ce code:

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

Et cela fonctionne très bien sur Android 2.3 mais pas sur 4.0. Après quelques recherches, j'entends qu'il vaut mieux utiliser AndroidHttpClient et de cette façon cela fonctionnera sur 4.0 et 3.1. Le problème c'est que je ne sais pas si j'ai correctement modifié mon code et qu'il n'y a pas trop d'exemples concernant AndroidhttpClient sur internet.

Voici mon code qui a été 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));

Voici ce que montre le 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)
26
Lara

StrictMode.ThreadPolicy a été introduit depuis le niveau 9 de l'API et la politique de thread par défaut a été modifiée depuis le niveau 11 de l'API, ce qui, en bref, ne permet pas au fonctionnement du réseau (notamment HttpClient et HttpUrlConnection) d'être exécuté sur le thread de l'interface utilisateur. si vous procédez ainsi, vous obtenez NetworkOnMainThreadException.

Cette restriction peut être modifiée en utilisant:

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

Ajoutez le code ci-dessus dans la méthode onCreate () de votre activité principale.

De plus, il est toujours recommandé de déplacer le fonctionnement du réseau hors du thread d'interface utilisateur, par exemple, en utilisant AsyncTask.

j'espère que cette aide.

72
yorkw

Utilisez un AsyncTask pour que la requête réseau ne bloque pas le thread d'interface utilisateur. La NetworkOnMainThreadException a été introduite depuis l'API version 11, ce qui explique pourquoi elle n'apparaît que 3.0 et plus.

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));
    }
}

Pour appeler ce fil simple, procédez comme suit.

new NetworkTask().execute(linkk);

Jetez un oeil à cet article écrit sur le Android. Il explique plus en détail comment écrire votre application pour gérer les threads.

32
Stefan Bossbaly