2012-08-15 78 views
8

我是新來的Android編程,並試圖在此示例程序中使用Web服務:android.os.NetworkOnMainThreadException的web服務(KSOAP)

我使用Android 4.1和我的IDE就是Eclipse朱諾。我認爲編程部分沒問題,但可能是連接問題。

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

不過,我得到這個錯誤:

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) 

那麼什麼可以是問題?

+0

您可以參考此問題。 [機器人-OS-networkonmainthreadexception換web服務-KSOAP] [1] [1]:http://stackoverflow.com/questions/8322057/android-os-networkonmainthreadexception-exception-while-試圖呼叫網絡服務 – 2012-08-15 12:15:00

回答

19

您無法在主線程上執行網絡操作。 結帳:http://developer.android.com/reference/android/os/AsyncTask.html

無痛背景線程:)

編輯:由於我仍然得到了贊成票這個答案即使它是幾年前我就不再建議使用的AsyncTask。它有許多已知的問題,這裏描述(http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/)。相反,我會敦促你使用Retrofit或者其他處理線程的好客戶端。

+0

謝謝我會嘗試:) – skynyrd 2012-08-16 07:09:25

+1

我試過了,現在完成了,再次感謝:)順便說一句,這個問題不會發生在Android 2.2 – skynyrd 2012-08-17 13:21:39

+0

那麼它仍然是最好的練習總是在後臺進行網絡操作,否則你的應用可能會顯示爲「laggy」。樂於幫助! – Slickelito 2012-08-17 13:40:02

11

完整的示例:

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

嘗試增加strictmode到您的應用程序。在您的onCreate方法中,添加

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

您的代碼在測試階段不推薦在最終代碼中使用,因爲它在主線程中強制運行它。 – 2014-04-23 13:11:42

相關問題