DefaultHttpClient to AndroidHttpClient
Asked Answered
F

2

26

I have a problem with my code and I was hoping for some help. I was firstly using this code :

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

And it works just fine on android 2.3 but on 4.0 it doesn't. After some research, I hear that is better to use AndroidHttpClient and this way it will work on 4.0 and 3.1. The problem is that I do not know whether I have modified my code correctly and there aren't too many examples regarding AndroidhttpClient on the internet.

Here is my code that was adjusted:

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

This is what the logcat shows:

     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)
Felipa answered 2/1, 2012 at 23:41 Comment(1)
Use the android recommended solution: tinyurl.com/88mctohPestana
P
72

StrictMode.ThreadPolicy was introduced since API Level 9 and the default thread policy had been changed since API Level 11, which in short, does not allow network operation (include HttpClient and HttpUrlConnection) get executed on UI thread. if you do this, you get NetworkOnMainThreadException.

This restriction can be changed, using:

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

Add the above code into your main activity's onCreate() method.

In addition, it is always recommended to move network operation off the UI thread, for example, using AsyncTask.

hope this help.

Presidency answered 3/1, 2012 at 1:21 Comment(6)
The whole point of these policies is to force good practice and emsure your application performs well. Turning the policies off is a bad idea. See Sbossb's answer for the right approach.Griner
@rgardler, read the answer carefully: it is always recommended to move network operation off the UI thread, for example, using AsyncTask. Thread policy was changed without highlighted and many consumer developer are not aware, it is worth to point out the exact reason why same code work in GingerBread but nor HoneyComb, Also note that AsyncTask is recommended but definitely not the only right approach.Presidency
@Presidency Ugh... why would you put this as the answer?!? Beginners looking for a quick fix aren't going to care... they are just going to copy and paste your code into their project and it'll be your fault when another crappy app gets published on the Android Market.Arcuation
There's no reason why you should ever disable StrictMode... it is there for a reason.Arcuation
Actually I am using an async http library which does the networking component in a background thread but passes control back to the caller.. Certain calls at that point can fail (but only on certain phones).. For instance if I try to shutdown the connection on the UI thread, even though it takes a really tiny amount of time it throws that exception. If i try to read data from the response (after the response has returned), I occasionally get that error as well.Gudrin
@Presidency thnx for your answer +1 for u its worked for me you save my lot of time...Trilbie
A
31

Use an AsyncTask so that the network request does not block the UI thread. The NetworkOnMainThreadException was introduced since API version 11, which is the reason why it is only showing up 3.0 and up.

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

To call this thread simple do this.

new NetworkTask().execute(linkk);

Take a look at this article written on the Android developer site. It explains in more detail how to write your app to handle threads.

Aquitaine answered 3/1, 2012 at 0:10 Comment(2)
I have tried this and it gives me an error that I can't solve. Here is what the logcat shows : 01-03 15:01:46.508: E/AndroidRuntime(23161): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 01-03 15:36:44.121: E/AndroidRuntime(24957): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)Felipa
I have commented the String link = params[0]; and I have also surrounded client.execute(request); with try/catchFelipa

© 2022 - 2024 — McMap. All rights reserved.