我正在运行一个简单的项目,点击android中的按钮。从Web服务返回显示的消息,其编码在java中完成。
这是我在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();
}
}
}
以下是我在Java中的代码:
@WebService(serviceName = "PracticeWebServices")
public class PracticeWebServices {
@WebMethod(operationName = "hello")
public String hello(@WebParam(name = "name") String name) {
return "Hello " + name + " !";
}
}
我在清单文件中包含了互联网权限....
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
现在,当我在Eclipse中提供的模拟器中运行该文件时。点击该按钮后,它会显示一条消息Unfortunately the program has stopped
当我检查logCat时....似乎我在 android.os.NetworkOnMainThreadException
中遇到异常答案 0 :(得分:2)
你不应该在主要线程中调用长时间守护进程,如互联网资源,磁盘上的数据,......你应该使用后台任务。否则,您会遇到ANR错误或编译错误。
答案 1 :(得分:2)
这里的问题只是你需要在一个单独的线程上进行Web服务调用(或者你有什么)。所以,很简单,你需要研究如何使用Android进行线程化。不幸的是,这可能有点痛苦,因为您需要在单独的线程上进行服务调用,但是您需要更新主线程上的UI。通常这需要在线程之间传递数据,这涉及处理程序或其他复杂性。幸运的是,Android平台提供了异步任务来处理这个问题,这可以缓解一些复杂性,并可以帮助您避免代码中的混乱。
将网络调用迁移到线程(或Android的异步任务)的有用文档
无痛线程(来自Android Developer docs) 异步任务(来自Android Developer docs) Android线程,处理程序和AsyncTask - 教程 设计响应性(来自Android开发人员文档)
答案 2 :(得分:2)
您应该将长网络抓取操作放在Thread
或AsyncTask
我建议您使用AsyncTask
您可以通过创建class
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();
}
}
}
您可以在onClick()
这样的
@Override
public void onClick(View v) {
if(v.getId()==submit_btn.getId()) {
new LongNetworkOperation.execute();
}
}
另外,我建议您在ProgressDialog
上显示onPreExecute()
并将其隐藏在onPostExecute()
中,以便用户了解长时间操作时强烈建议的漫长后台进程< / p>
答案 3 :(得分:1)
您不应该在主线程上运行网络请求,这会导致NetworkOnMainThreadException
。请使用自定义AsyncTask
查看this solution或使用以下其中一个库: