从Android调用WSDL会导致NetworkOnMainThreadException

时间:2014-04-15 08:36:09

标签: android web-services wsdl

以下是此示例代码(MainActivity):

private static final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static final String METHOD_NAME = "CelsiusToFahrenheit";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
TextView tv;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tv = (TextView)findViewById(R.id.text1);

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("Celsius", "32");

    SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
    soapEnvelope.dotNet = true;
    soapEnvelope.setOutputSoapObject(request);

    HttpTransportSE aht = new HttpTransportSE(URL);

    try {
        aht.call(SOAP_ACTION, soapEnvelope);
        SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
        tv.setText("Status: " + resultString);
    } catch (Exception e) {
        tv.setText("Problem: " + e.toString());
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

...

当我运行此代码时,我收到此消息问题:android.os.NetworkOnMainThreadException。 在manifest.xml中添加了

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

线。 Here 是整个android项目。

有人知道如何更改此代码吗? 提前感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:2)

当Android应用程序尝试在其主线程上执行网络操作时,抛出此异常。您必须在AsyncTask中运行代码。你的代码看起来像这样 您可以将resultString声明为实例变量

class SoapTask extends AsyncTask<String, Void, Void> {

    private Exception exception;

        @Override
    protected Void doInBackground(Void... arg0) {
        try {
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            request.addProperty("Celsius", "32");

            SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
            soapEnvelope.dotNet = true;
            soapEnvelope.setOutputSoapObject(request);

            HttpTransportSE aht = new HttpTransportSE(URL);

            try {
                aht.call(SOAP_ACTION, soapEnvelope);
                resultString = "Status:" + (SoapPrimitive)soapEnvelope.getResponse(); 
            } catch (Exception e) {
                resultString = "Problem:" + e.toString();
            }
        }

    protected void onPostExecute(Void result) {
         tv.setText("Status: " + resultString);
    }
}

答案 1 :(得分:0)

试试这个..

当您在其主线程上执行网络操作时,

NetworkOnMainThreadException抛出。

所以你必须在AsyncTask

中运行网络操作

你可以像下面那样调用AsyncTask

new SerializationConnection().execute(URL);

然后SerializationConnection class

class SerializationConnection extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {
        try {
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            request.addProperty("Celsius", "32");

            SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
            soapEnvelope.dotNet = true;
            soapEnvelope.setOutputSoapObject(request);

            HttpTransportSE aht = new HttpTransportSE(urls[0]);
            aht.call(SOAP_ACTION, soapEnvelope);
            SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
            return "Status: " + resultString;
        } catch (Exception e) {
            return "Problem: " + e.toString();
        }
    }

    protected void onPostExecute(String result) {
        tv.setText(result);
    }
}

答案 2 :(得分:0)

您正在主线程中进行服务器调用。如果您的目标版本是9

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

为了更好的方式尝试使用AsynTask