问题
I Try To Receive Data From A Web-Service Using This Code But An Fatal-Error Occurred
package com.example.lo2i05;
import java.io.IOException;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
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 org.xmlpull.v1.XmlPullParserException;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private static String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static String NAMESPACE = "http://tempuri.org/";
private static String METHOD_NAME = "CelsiusToFahrenheit";
private static String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
private TextView tv;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.txt);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View arg0)
{
final SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius","32");
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try
{
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
String r = result.toString();
tv.setText(r);
}
catch (IOException e)
{
tv.setText("1");
}
catch (XmlPullParserException e)
{
tv.setText("2");
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
This Is A LogCat
11-24 23:04:03.100: W/IInputConnectionWrapper(1155): getSelectedText on inactive InputConnection
11-24 23:04:03.100: W/IInputConnectionWrapper(1155): setComposingText on inactive InputConnection
11-24 23:04:03.100: W/IInputConnectionWrapper(1155): getExtractedText on inactive InputConnection
11-24 23:04:08.135: D/GestureDetector(1155): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 2 mFalseSizeCnt:0
11-24 23:04:08.165: D/AndroidRuntime(1155): Shutting down VM
11-24 23:04:08.165: W/dalvikvm(1155): threadid=1: thread exiting with uncaught exception (group=0x412862a0)
11-24 23:04:08.170: E/AndroidRuntime(1155): FATAL EXCEPTION: main
11-24 23:04:08.170: E/AndroidRuntime(1155): android.os.NetworkOnMainThreadException
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
11-24 23:04:08.170: E/AndroidRuntime(1155): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
11-24 23:04:08.170: E/AndroidRuntime(1155): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
11-24 23:04:08.170: E/AndroidRuntime(1155): at java.net.InetAddress.getAllByName(InetAddress.java:214)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpEngine.connect(HttpEngine.java:310)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
11-24 23:04:08.170: E/AndroidRuntime(1155): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)
11-24 23:04:08.170: E/AndroidRuntime(1155): at org.ksoap2.transport.ServiceConnectionSE.openOutputStream(ServiceConnectionSE.java:109)
11-24 23:04:08.170: E/AndroidRuntime(1155): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:157)
11-24 23:04:08.170: E/AndroidRuntime(1155): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:96)
11-24 23:04:08.170: E/AndroidRuntime(1155): at com.example.lo2i05.MainActivity$1.onClick(MainActivity.java:46)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.view.View.performClick(View.java:4223)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.view.View$PerformClick.run(View.java:17275)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.os.Handler.handleCallback(Handler.java:615)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.os.Handler.dispatchMessage(Handler.java:92)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.os.Looper.loop(Looper.java:137)
11-24 23:04:08.170: E/AndroidRuntime(1155): at android.app.ActivityThread.main(ActivityThread.java:4898)
11-24 23:04:08.170: E/AndroidRuntime(1155): at java.lang.reflect.Method.invokeNative(Native Method)
11-24 23:04:08.170: E/AndroidRuntime(1155): at java.lang.reflect.Method.invoke(Method.java:511)
11-24 23:04:08.170: E/AndroidRuntime(1155): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
11-24 23:04:08.170: E/AndroidRuntime(1155): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
11-24 23:04:08.170: E/AndroidRuntime(1155): at dalvik.system.NativeStart.main(Native Method)
11-24 23:09:16.970: I/Process(1155): Sending signal. PID: 1155 SIG: 9
Android Version : 4.2 (Jelly Bean).
I Added A Permission To the Manifest To Access The Internet .
New CODE (1.0)
package com.example.lo2i05;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private static String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static String NAMESPACE = "http://tempuri.org/";
private static String METHOD_NAME = "CelsiusToFahrenheit";
private static String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
private TextView tv;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.txt);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View arg0)
{
final SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius","32");
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
new AsyncTask<Void, Void, Boolean>() {
SoapObject obj;
@Override
protected Boolean doInBackground(Void... params) {
//here you can do your background network job
try{ HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
obj = (SoapObject)envelope.getResponse();
return true; }
catch (Exception e) {e.printStackTrace();
return false;}}
@Override
protected void onPostExecute(Boolean result) {
//here you can do your UI job
if (!result)
tv.setText("Error");
else
tv.setText(obj.getProperty(0).toString());
super.onPostExecute(result);
}
}.execute();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
=======================================
LogCat
11-24 23:37:34.120: E/Trace(2671): error opening trace file: No such file or directory (2)
11-24 23:37:34.235: D/libEGL(2671): loaded /system/lib/egl/libEGL_mali.so
11-24 23:37:34.240: D/libEGL(2671): loaded /system/lib/egl/libGLESv1_CM_mali.so
11-24 23:37:34.240: D/libEGL(2671): loaded /system/lib/egl/libGLESv2_mali.so
11-24 23:37:34.245: D/(2671): Device driver API match
11-24 23:37:34.245: D/(2671): Device driver API version: 10
11-24 23:37:34.245: D/(2671): User space API version: 10
11-24 23:37:34.245: D/(2671): mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Wed Sep 12 17:53:53 KST 2012
11-24 23:37:34.275: D/OpenGLRenderer(2671): Enabling debug mode 0
11-24 23:37:35.895: D/GestureDetector(2671): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 2 mFalseSizeCnt:0
11-24 23:37:50.615: W/System.err(2671): java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive cannot be cast to org.ksoap2.serialization.SoapObject
11-24 23:37:50.615: W/System.err(2671): at com.example.lo2i05.MainActivity$1$1.doInBackground(MainActivity.java:48)
11-24 23:37:50.615: W/System.err(2671): at com.example.lo2i05.MainActivity$1$1.doInBackground(MainActivity.java:1)
11-24 23:37:50.620: W/System.err(2671): at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-24 23:37:50.620: W/System.err(2671): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-24 23:37:50.620: W/System.err(2671): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-24 23:37:50.620: W/System.err(2671): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-24 23:37:50.620: W/System.err(2671): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-24 23:37:50.620: W/System.err(2671): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-24 23:37:50.620: W/System.err(2671): at java.lang.Thread.run(Thread.java:856)
11-24 23:38:05.935: W/IInputConnectionWrapper(2671): getSelectedText on inactive InputConnection
11-24 23:38:05.935: W/IInputConnectionWrapper(2671): setComposingText on inactive InputConnection
11-24 23:38:05.935: W/IInputConnectionWrapper(2671): getExtractedText on inactive InputConnection
回答1:
Try to asynchronously like this:
public class MainActivity extends Activity {
private static String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static String NAMESPACE = "http://tempuri.org/";
private static String METHOD_NAME = "CelsiusToFahrenheit";
private static String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
private TextView tv;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.txt);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View arg0)
{
new MyTask().execute();
}
});
}
public class MyTask extends AsyncTask<Void, Void, String> {
ProgressDialog progress;
String response = "";
public void onPreExecute() {
super.onPreExecute();
}
@Override
protected Stirng doInBackground(Void... arg0) {
final SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius","32");
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try
{
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
response = result.toString();
}
catch (IOException e)
{
response = "1";
}
catch (XmlPullParserException e)
{
response = "2";
}
return response;
}
@Override
public void onPostExecute(String res) {
if(!(res.equalsIgnoreCase("")))
{
tv.setText(res);
}
}
}
}
Just try this now
回答2:
Check this out http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html. As per official doc if you are using Honeycomb SDK or above your should not put network operation on the main/UI thread. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged since it would block the UI and can cause ANR.
You need to use an background thread or AsyncTask
for network operation to avoid getting this exception.
As a general rule always put time consuming task in background thread or AsyncTask
.
EDIT:
Change following line in your code
obj = (SoapObject)envelope.getResponse();
to
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
来源:https://stackoverflow.com/questions/13545151/error-with-calling-a-web-service-and-receiving-data