2013-01-15 124 views
1

我正在运行一个简单的项目,点击android中的按钮。显示的消息从webservice返回,其编码是在java中完成的。从android中调用java webservices

这是我在Eclipse项目的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 + " !"; 
    } 
} 

我已经包括在清单文件中的Internet权限....

<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

'NetworkOnMainThreadException'因为主线程上的网络 –

+1

NetworkOnMainThreadException dups无处不在,[this](http://stackoverflow.com/questions/63 43166/android-os-networkonmainthreadexception)[this2](http://stackoverflow.com/questions/5150637/networkonmainthreadexception) – wtsang02

回答

2

你应该把你长的网络在任何一个ThreadAsyncTask

读取操作

我建议你使用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(); 
    } 
} 

此外,我建议你展现一个ProgressDialogonPreExecute()并把它藏在onPostExecute()这样用户便可得知长背景强烈建议长时间运行的进程

2

你不应该调用在很长一段时间看管器处理像互联网资源的主线程,磁盘上的数据......你应该改用后台任务。否则,你会提到ANR错误或编译错误。

2

这里的问题很简单,你需要在一个单独的线程上调用Web服务调用(或者你所拥有的)。所以,很简单,您需要研究如何使用Android进行线程化。不幸的是,这可能有点痛苦,因为你需要在一个单独的线程上进行服务调用,但是你需要更新主线程上的UI。通常这需要在线程之间传递数据,这涉及到处理程序或其他复杂性。幸运的是,Android平台提供了异步任务来处理这个问题,这减轻了一些复杂性,并可能帮助您避免代码中的混乱。

有用的文档迁移网络调用线程(或Android的异步任务)

无痛线程(从Android开发者文档) 异步任务(从Android开发者文档) Android的线程,处理程序和的AsyncTask - 教程 设计响应能力(来自Android开发者文档)

1

您遇到的问题是网络操作一样你所要做的不能也不应该在主UI线程上执行。这样做会导致ANR(Android Not Responding),这正是您刚刚获得的错误。你想要做的是将你的代码移动到一个单独的线程或一个AsyncTask,它将在不同的线程使用方法在后台执行此操作,该方法无法访问主UI线程上的视图。例如,

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

} 

然后,所有你需要做的就是调用任何你想使用它的AsyncTask:new ExampleOperation().execute();