Arjun K P
Arjun K P

Reputation: 2111

call java webservices from android

I am running a simple project where on clicking a button in android. A message is displayed returned from a webservice whose coding is done in java.

Here is my program in eclipse for Android:

@Override
public void onClick(View v) {
    final String url = "http://10.0.2.2:8050/WebPractice/PracticeWebServices?wsdl";
    final String namespace = "http://PracticeWebServices/";
    final String methodName = "hello";
    final String action = namespace + methodName;

    if(v.getId() == submit_btn.getId()) {
        SoapObject so = new SoapObject(namespace, methodName);
        so.addProperty("name", "Arjun");
        SoapSerializationEnvelope sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        sse.setOutputSoapObject(so);
        HttpTransportSE hse = new HttpTransportSE(url);

        try {
            hse.call(action, sse);
            SoapPrimitive primitive = (SoapPrimitive)sse.getResponse();
            Toast.makeText(getApplicationContext(),primitive.toString() , Toast.LENGTH_SHORT);
        } catch(IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

Following is my code in Java:

@WebService(serviceName = "PracticeWebServices")
public class PracticeWebServices {

    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String name) {
        return "Hello " + name + " !";
    }
}

I've included the internet permission in manifest file....

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Now, when I'm running the file in the emulator provided in Eclipse. On clicking the button it shows me a message Unfortunately the program has stopped

When i checked the logCat....Seems like i m hitting an exception at android.os.NetworkOnMainThreadException

Upvotes: 1

Views: 1672

Answers (5)

ajmal
ajmal

Reputation: 4252

You should put your long networking fetching operation in either a Thread or AsyncTask

I suggest you to use AsyncTask

you can do something like this by creating a class that extends AsyncTask

private class LongNetworkOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {

        SoapObject so = new SoapObject(namespace, methodName);
        so.addProperty("name", "Arjun");
        SoapSerializationEnvelope sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        sse.setOutputSoapObject(so);
        HttpTransportSE hse = new HttpTransportSE(url);

        try {
            hse.call(action, sse);
            SoapPrimitive primitive = (SoapPrimitive)sse.getResponse();
            Toast.makeText(getApplicationContext(),primitive.toString() , Toast.LENGTH_SHORT);
        } catch(IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

and you can call it on your onClick() like this

@Override
public void onClick(View v) {
    if(v.getId()==submit_btn.getId()) {
        new LongNetworkOperation.execute();
    }
}

Also I suggest you to show a ProgressDialog on onPreExecute() and hide it in onPostExecute() so that the user will be aware of the long background process which is highly recommended for long operations

Upvotes: 2

Karey Powell
Karey Powell

Reputation: 482

The problem that you are having is network operation like what you are trying to do cannot and should not be performed on the main UI thread. Doing so will lead to an ANR (Android Not Responding), which is exactly the kind of error you are getting just now. What you want to do is move your code to a separate thread or to an AsyncTask that will perform this action in the background on a different thread using the doInBackground() method which does not have access to your views on the main UI thread. For example,

private class ExampleOperation extends AsyncTask<String, Void, String> {

    public ExampleOperation() { //ctor }

    @Override
    protected void onPreExecute() {
        // things that you want to initialize and maybe show dialog to user.
    }

    @Override
    protected String doInBackground(String... params) {
       // this is where you perform that network related operation.  
    }

    @Override
    protected void onPostExecute(String result) {
       // this is where get the results from the network related task.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
       // you can update your progressbar if any; otherwise omit method.
    }

}

Then all you have to do is call the AsyncTask where ever you want to use it: new ExampleOperation().execute();

Upvotes: 1

saschoar
saschoar

Reputation: 8230

You should not run your network requests on the main thread, this is causing a NetworkOnMainThreadException. See this solution with a custom AsyncTask or use one of these libraries:

Upvotes: 1

Ramesh Sangili
Ramesh Sangili

Reputation: 1631

The problem here is simply that you need to make your web service calls (or what-have-you) on a separate thread. So, quite simply, you’ll need to look into how to do threading with Android. Unfortunately this can be a bit of a pain because you need to make your service calls on a separate thread, but you need to update the UI on the main thread. Normally this would require passing data between the threads, which involves handlers or other complexities. Luckily the Android platform provides the Async Task to handle this, which alleviates some of this complexity and may help you avoid some clutter in your code.

Useful documentation to migrate your network calls to threads (or Android’s Async Task)

Painless Threading (from the Android Developer docs) Async Task (from the Android Developer docs) Android Threads, Handlers and AsyncTask – Tutorial Designing for Responsiveness (from the Android Developer docs)

Upvotes: 2

gezdy
gezdy

Reputation: 3322

You should not call long time keeper process in the main thread like internet resources, data on disk, ... You should instead use a background task. Otherwise you will have ANR error or compilation error like you mention it.

Upvotes: 2

Related Questions