2

I'm using AsyncTask to send POST request to webservice, but I keep getting NetworkOnMainThreadException exception. I'm using solution from answer from this question : How to fix android.os.NetworkOnMainThreadException? but I can't make it working. My classes:

public class MainActivity extends Activity {

    public JSONObject result;
    public String retSrc;
    public HttpEntity resEntity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        try {
            resEntity = new UpdateData().execute().get();     
            retSrc = EntityUtils.toString(resEntity);         // Here I get an exception
            result = new JSONObject(retSrc);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    private class UpdateData extends AsyncTask<String, Void, HttpEntity>{

        private HttpEntity entit;
            @Override
            protected HttpEntity doInBackground(String... params) {
                try {
                    HttpClient client = new DefaultHttpClient();  
                    String postURL = "http://www.test.com";
                    HttpPost post = new HttpPost(postURL);
                        List<NameValuePair> crc = new ArrayList<NameValuePair>();
                        crc.add(new BasicNameValuePair("crc", "test"));
                        UrlEncodedFormEntity ent = new UrlEncodedFormEntity(crc,HTTP.UTF_8);
                        post.setEntity(ent);
                        HttpResponse responsePOST = client.execute(post);  
                        entit = responsePOST.getEntity();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return entit;
            }
    }
}

And here is error log:

12-03 14:46:36.929: E/AndroidRuntime(3044): FATAL EXCEPTION: main
12-03 14:46:36.929: E/AndroidRuntime(3044): java.lang.RuntimeException: Unable to start activity ComponentInfo{app/app.MainActivity}: android.os.NetworkOnMainThreadException
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.Looper.loop(Looper.java:137)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.main(ActivityThread.java:4424)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.lang.reflect.Method.invokeNative(Native Method)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.lang.reflect.Method.invoke(Method.java:511)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at dalvik.system.NativeStart.main(Native Method)
12-03 14:46:36.929: E/AndroidRuntime(3044): Caused by: android.os.NetworkOnMainThreadException
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:161)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:175)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.exhaustInputStream(ChunkedInputStream.java:289)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:262)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.BasicManagedEntity.streamClosed(BasicManagedEntity.java:179)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:266)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:213)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.io.InputStreamReader.close(InputStreamReader.java:145)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:139)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at pl.lodz.uni.uniinformator.MainActivity.onCreate(MainActivity.java:43)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.Activity.performCreate(Activity.java:4465)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
12-03 14:46:36.929: E/AndroidRuntime(3044):     ... 11 more

If I understand correctly method doInBackground should do everything what's inside as it would be in another thread.

Community
  • 1
  • 1
dziwna
  • 1,212
  • 2
  • 14
  • 25
  • 2
    Out of curiosity, why can not you process the Entity inside the doInBackground and return the JSONObject? – Blackbelt Dec 03 '12 at 13:20

4 Answers4

2

As you said, you're getting your error in this line:

retSrc = EntityUtils.toString(resEntity);

It's because EntityUtils.toString() should also be situated in doInBackground() method.

Piotr Chojnacki
  • 6,837
  • 5
  • 34
  • 65
2

- Its always better practice to have the UI work on UI-Thread and Non-UI work on Non-UI Thread, but from HoneyComb version of Android it became a Law.

- In your case get() is a blocking call, which you are calling from UI thread, where as it should be on the Non-UI thread.

- EntityUtils.toString(resEntity) should be in the Non-UI thread, so it should be in the doInBackground() method.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
1

the get() is a blocking call, you can not execute blocking call on the UI Thread

From the AsyncTask doc

Waits if necessary for the computation to complete, and then retrieves its result.

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
1

From the ICS and above versions Android won't allowed any network operation in the UI thread.It should be done in separate thread so it won't hang the UI.Try your network communication code in the separate thread.

AndroidLearner
  • 4,500
  • 4
  • 31
  • 62