2012-08-15 17 views
8

yo soy nuevo en la programación androide y tratando de utilizar servicio web en este programa de ejemplo:android.os.NetworkOnMainThreadException de servicio web (ksoap)

que utilizan Android 4.1 y mi IDE Eclipse es Juno. Creo que la parte de programación está bien, pero puede haber un problema de conexión.

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 String NAMESPACE = "http://tempuri.org/"; 
    final static String METHOD_NAME = "CelsiusToFahrenheit"; 
    final static String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit"; 
    final static String 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().toString()); 

       //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. 
       String 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; 
    } 
} 

Sin embargo, me sale este error:

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.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.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.<init>(HttpConnection.java:70) 
08-15 11:45:26.294: E/AndroidRuntime(641): at libcore.net.http.HttpConnection.<init>(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) 

Entonces, ¿cuál puede ser el problema?

+0

Puede consultar esta pregunta. [androide-os-networkonmainthreadexception-para-servicio web-ksoap] [1] [1]: http://stackoverflow.com/questions/8322057/android-os-networkonmainthreadexception-exception-while- try-to-call-a-webserv –

Respuesta

19

No puede hacer operaciones de red en el hilo principal. Pedido: http://developer.android.com/reference/android/os/AsyncTask.html

indoloro para el fondo roscado :)

EDIT: Dado que todavía estoy levantando-votos para esta respuesta aunque es varios años ya no se recomienda usar AsyncTask. Tiene muchos problemas conocidos que se describen aquí (http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/). En su lugar, le instaría a utilizar Retrofit o uno de los otros buenos clientes http que maneja el subproceso por usted.

+0

Gracias, intentaré eso :) – skynyrd

+1

Lo intenté y ya está hecho, gracias de nuevo :) Por cierto, este problema no ocurre en Android 2.2 – skynyrd

+0

Bueno, sigue siendo el mejor practique siempre haga operaciones de red en segundo plano, de lo contrario su aplicación podría aparecer como "laggy". ¡Feliz de ayudar! – Slickelito

11

ejemplo completo:

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 String 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<Void, Void, Void> { 
     @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() 
    { 
     String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit"; 
     String METHOD_NAME = "CelsiusToFahrenheit"; 
     String NAMESPACE = "http://tempuri.org/"; 
     String 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 resultString = (SoapPrimitive)soapEnvelope.getResponse(); 

      Log.i(TAG, "Result Celsius: " + resultString); 
     } 
     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 resultString = (SoapPrimitive)soapEnvelope.getResponse(); 

      Log.i(TAG, "Result Fahrenheit: " + resultString); 
     } 
     catch(Exception ex) { 
      Log.e(TAG, "Error: " + ex.getMessage()); 
     } 
    } 

} 
4

Trate de añadir StrictMode a su aplicación. En su método onCreate, agregue

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

Es recomendable utilizar su código durante la fase de prueba, no en el código final, ya que lo ejecuta con fuerza en el hilo principal. –