Reputation: 2111
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
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
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
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
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
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