android.os.NetworkOnMainThreadException pour webservice (ksoap)

Je suis nouveau dans la programmation Android et j’essaie d’utiliser Webservice dans cet exemple de programme:

J’utilise Android 4.1 et mon IDE est Eclipse Juno. Je pense que la partie programmation est correcte mais qu’il existe peut-être un problème de connexion.

package com.example.webserviceexample; import java.io.IOException; import org.ksoap2.SoapEnvelope; import org.ksoap2.SoapFault; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapPrimitive; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import org.xmlpull.v1.XmlPullParserException; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { final static Ssortingng NAMESPACE = "http://tempuri.org/"; final static Ssortingng METHOD_NAME = "CelsiusToFahrenheit"; final static Ssortingng SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit"; final static Ssortingng URL = "http://www.w3schools.com/webservices/tempconvert.asmx"; TextView sonuc; EditText deger; Button hesapla; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); deger = (EditText) findViewById(R.id.deger); sonuc = (TextView) findViewById(R.id.flag); hesapla = (Button) findViewById(R.id.hesapla); hesapla.setOnClickListener(new OnClickListener() { public void onClick(View v) { //request info SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); Request.addProperty("Celcius",deger.getText().toSsortingng()); //envelope SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); soapEnvelope.dotNet = true; //.NET = true, php = false //putting request to the envelope soapEnvelope.setOutputSoapObject(Request); //transferring data HttpTransportSE aht = new HttpTransportSE(URL); //prepare //start try { aht.call(SOAP_ACTION, soapEnvelope); } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } //waiting and getting response. Ssortingng result; try { // we are creating SoapPrimitive Object as waiting for simple variable. result = "Fahrenheit:" + soapEnvelope.getResponse(); //writing the result to the textView sonuc.setText(result); } catch (SoapFault e) { e.printStackTrace(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } 

Cependant, j’obtiens cette erreur:

 08-15 11:45:26.294: E/AndroidRuntime(641): FATAL EXCEPTION: main 08-15 11:45:26.294: E/AndroidRuntime(641): android.os.NetworkOnMainThreadException 08-15 11:45:26.294: E/AndroidRuntime(641): at android.os.SsortingctMode$AndroidBlockGuardPolicy.onNetwork(SsortingctMode.java:1117) 08-15 11:45:26.294: E/AndroidRuntime(641): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 08-15 11:45:26.294: E/AndroidRuntime(641): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 08-15 11:45:26.294: E/AndroidRuntime(641): at java.net.InetAddress.getAllByName(InetAddress.java:214) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnection.(HttpConnection.java:70) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnection.(HttpConnection.java:50) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:341) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpEngine.connect(HttpEngine.java:310) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239) 08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 08-15 11:45:26.294: E/AndroidRuntime(641): at org.ksoap2.transport.ServiceConnectionSE.connect(ServiceConnectionSE.java:76) 08-15 11:45:26.294: E/AndroidRuntime(641): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:146) 08-15 11:45:26.294: E/AndroidRuntime(641): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:95) 08-15 11:45:26.294: E/AndroidRuntime(641): at com.example.webserviceexample.MainActivity$1.onClick(MainActivity.java:61) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.view.View.performClick(View.java:4084) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.view.View$PerformClick.run(View.java:16966) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.os.Handler.handleCallback(Handler.java:615) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.os.Handler.dispatchMessage(Handler.java:92) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.os.Looper.loop(Looper.java:137) 08-15 11:45:26.294: E/AndroidRuntime(641): at android.app.ActivityThread.main(ActivityThread.java:4745) 08-15 11:45:26.294: E/AndroidRuntime(641): at java.lang.reflect.Method.invokeNative(Native Method) 08-15 11:45:26.294: E/AndroidRuntime(641): at java.lang.reflect.Method.invoke(Method.java:511) 08-15 11:45:26.294: E/AndroidRuntime(641): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 08-15 11:45:26.294: E/AndroidRuntime(641): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 08-15 11:45:26.294: E/AndroidRuntime(641): at dalvik.system.NativeStart.main(Native Method) 

Alors, quel peut être le problème?

Vous ne pouvez pas effectuer d’opérations réseau sur le thread principal. Commander: http://developer.android.com/reference/android/os/AsyncTask.html

pour un enfilage de fond sans douleur 🙂

EDIT: Depuis que je reçois toujours des votes positifs pour cette réponse même si elle a plusieurs années, je ne suggérerais plus d’utiliser AsyncTask. Il a beaucoup de problèmes connus qui sont décrits ici ( http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/ ). Au lieu de cela, je vous exhorterais à utiliser Retrofit ou l’un des autres gentils clients http qui gère le threading pour vous.

Exemple complet:

 import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapPrimitive; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; public class MainActivity extends Activity { private Ssortingng TAG ="Vik"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AsyncCallWS task = new AsyncCallWS(); task.execute(); } private class AsyncCallWS extends AsyncTask { @Override protected Void doInBackground(Void... params) { Log.i(TAG, "doInBackground"); calculate(); return null; } @Override protected void onPostExecute(Void result) { Log.i(TAG, "onPostExecute"); } @Override protected void onPreExecute() { Log.i(TAG, "onPreExecute"); } @Override protected void onProgressUpdate(Void... values) { Log.i(TAG, "onProgressUpdate"); } } public void calculate() { Ssortingng SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit"; Ssortingng METHOD_NAME = "CelsiusToFahrenheit"; Ssortingng NAMESPACE = "http://tempuri.org/"; Ssortingng URL = "http://www.w3schools.com/webservices/tempconvert.asmx"; try { SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); Request.addProperty("Celsius", "32"); SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); soapEnvelope.dotNet = true; soapEnvelope.setOutputSoapObject(Request); HttpTransportSE transport= new HttpTransportSE(URL); transport.call(SOAP_ACTION, soapEnvelope); SoapPrimitive resultSsortingng = (SoapPrimitive)soapEnvelope.getResponse(); Log.i(TAG, "Result Celsius: " + resultSsortingng); } catch(Exception ex) { Log.e(TAG, "Error: " + ex.getMessage()); } SOAP_ACTION = "http://tempuri.org/FahrenheitToCelsius"; METHOD_NAME = "FahrenheitToCelsius"; try { SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); Request.addProperty("Fahrenheit", "100"); SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); soapEnvelope.dotNet = true; soapEnvelope.setOutputSoapObject(Request); HttpTransportSE transport= new HttpTransportSE(URL); transport.call(SOAP_ACTION, soapEnvelope); SoapPrimitive resultSsortingng = (SoapPrimitive)soapEnvelope.getResponse(); Log.i(TAG, "Result Fahrenheit: " + resultSsortingng); } catch(Exception ex) { Log.e(TAG, "Error: " + ex.getMessage()); } } } 

Essayez d’append ssortingctmode à votre application. Dans votre méthode onCreate, ajoutez

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