dziwna
dziwna

Reputation: 1242

NetworkOnMainThreadException while sending POST request to webservice

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.

Upvotes: 2

Views: 468

Answers (4)

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33534

- 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.

Upvotes: 2

AndroidLearner
AndroidLearner

Reputation: 4636

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.

Upvotes: 1

Blackbelt
Blackbelt

Reputation: 157437

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.

Upvotes: 1

Piotr Chojnacki
Piotr Chojnacki

Reputation: 6857

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.

Upvotes: 2

Related Questions