Android – Webservice client with android.os.NetworkOnMainThreadException error

androidwebservice-client

my aim is to call a .Net webservice (.asmx) from Android Device.

.Net Webservice is tested using a .net test client and using SOAPUI application.

i'm using Eclipse to build the android application – included KSOAP2 project for webservice call. Application has android.permission.INTERNET tag is included in user-permission section.

i'm having two issues
[1] Application throws "android.os.NetworkOnMainThreadException" error if i invoke the webservice method from onCreate() (code below) (many of the examples i have seen in internet are of same approach, but i don't know why it is failing in my project)

[2] To resolve the above issue i created a class inside "MainActivity" but now i'm getting "source not found" message on line client.execute("some text as input")
(checked the build path, there is ref to KSOAP2 jar file and no compilation error)

What is the correct approach and how to resolve this issue please? Thanks for your help

Code of [issue 1]

    //This code for calling .net webservice from Android devide.. and throws "android.os.NetworkOnMainThreadException" whilst calling.

    package com.example.wsclient;

    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransportSE;

    import android.os.Bundle;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.view.Menu;
    import android.widget.TextView;

    public class MainActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            String SOAP_ACTION = "http://mycomp.org/GetParticipantVote";
            String METHOD_NAME = "GetParticipantVote";
            String NAMESPACE = "http://mycomp.org/";
            String URL = "http://10.0.2.2:8080/WSRating.asmx";

            try {
                SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
                request.addProperty("sID", "My_name");
                request.addProperty("sRate", "9");

                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                envelope.dotNet=true;

                envelope.setOutputSoapObject(request);
                HttpTransportSE  androidHttpTransport = new HttpTransportSE (URL);
                androidHttpTransport.call(SOAP_ACTION, envelope);
                SoapObject result=(SoapObject)envelope.getResponse();

                //To get the data.
                String resultData=result.getProperty(0).toString();

                AlertDialog alertDialog = new AlertDialog.Builder(this).create();
                alertDialog.setTitle("Webservice Client");
                alertDialog.setMessage("Webservice Resp : " +  resultData);
                alertDialog.show();

            }
            catch (Exception eE) {

                AlertDialog alertDialog1 = new AlertDialog.Builder(this).create();
                alertDialog1.setTitle("Webservice Client");
                alertDialog1.setMessage("Error : " +  eE.getMessage());
                alertDialog1.show();
           }
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
    }

Code of [issue 2] —

            package com.example.wsclient;

            import org.ksoap2.SoapEnvelope;
            import org.ksoap2.serialization.SoapObject;
            import org.ksoap2.serialization.SoapSerializationEnvelope;
            import org.ksoap2.transport.HttpTransportSE;

            import android.os.Bundle;
            import android.app.Activity;
            import android.app.AlertDialog;
            import android.view.Menu;
            import android.widget.TextView;

            public class MainActivity extends Activity {
                @Override
                public void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);

                    CallWS client = new CallWS();
                    client.execute("some text as input");

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

                    /* AsyncTask class to remove android.os.NetworkOnMainThreadException error */
                    private class CallWS extends AsyncTask<String, Integer, String> {

                         protected String doInBackground(String... sValues) {

                                String resultData;

                                String SOAP_ACTION = "http://mycomp.org/GetParticipantVote";
                                String METHOD_NAME = "GetParticipantVote";
                                String NAMESPACE = "http://mycomp.org/";
                                String URL = "http://10.0.2.2:8080/WSRating.asmx";

                                try {
                                    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
                                    request.addProperty("sID", "My_name");
                                    request.addProperty("sRate", "9");

                                    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                                    envelope.dotNet=true;

                                    envelope.setOutputSoapObject(request);
                                    HttpTransportSE  androidHttpTransport = new HttpTransportSE (URL);
                                    androidHttpTransport.call(SOAP_ACTION, envelope);
                                    SoapObject result=(SoapObject)envelope.getResponse();

                                    //To get the data.
                                    resultData =result.getProperty(0).toString();
                                }
                                catch (Exception eE) {
                                    resultData = "Error : " +  eE.getMessage();
                               }

                               return resultData
                         }

                         protected void onProgressUpdate(Integer... values) {

                         }

                         protected void onPostExecute(String result) {
                             // do something here to display the result...
                         }
                     }

                     }

Best Answer

My best guess is that you're testing this solution on the ICS.

You can for quick test purpouses use Strick Mode: http://developer.android.com/reference/android/os/StrictMode.html.

In ICS all network actions on UI are forbidden, that is why you need to rebuild it to use AsyncTasks, http://developer.android.com/reference/android/os/AsyncTask.html.