[英]KSoap2 on Android freezing the device instead of making a webservice call
我正在尝试连接到我为接收来自 Android 设备的 SOAP 调用而创建的.NET 4.0 Web 服务,现在托管在本地 IIS 上以进行测试。
我发现ksoap2将是一个很好的类库,可以做我想做的事情。 从https://code.google.com/p/ksoap2-android/下载了 .jar 包,并开始用我的手指在狂喜中敲击键盘。
发送的信息量从几千字节到几兆字节不等。
HttpTransportSE.call(String, SoapSerializationEnvelope)
-method 仍然在 Eclipse 的 Android 模拟器中运行完美,将调用发送到本地 IIS 中托管的 web 服务。 甚至测试了 web 服务在尝试从同一局域网中的 web 浏览器打开服务地址时收到空调用。
当我将 .apk 文件复制到 Android 设备,安装它,启动它并尝试拨打电话时,整个程序在没有拨打电话的情况下冻结。
正如您从代码块中看到的,在考虑了可能的错误之后,出现了一些行:在模拟环境中,成功调用会返回一个SoapPrimitive 对象或流入正确的catch 块,根据当前的情况为用户生成错误消息情况。
然后在实时 Android 设备上,程序将永远失去响应能力,必须从应用程序菜单中终止。
我从异步方法中删除了调用,并尝试直接从为按钮单击事件分配的匿名内部函数中调用它。
试着不试图得到回应,只是拨打电话。
尝试为设备获取一个 logcat 程序以查看 UI 背后发生的事情,发现两个,他们需要 root 访问权限,而我在设备中没有。 这就是为什么我没有任何 logcat 向您展示,并且显示模拟器 logcat 可能(?)没用,因为它在那里工作正常。
不尝试连接到本地主机。
尝试在运行Android 4.2.2 的较旧联想平板电脑和全新的三星 Galaxy Tab 上安装该程序,两者都会遇到相同的问题,但否则运行良好。
这是在设备/模拟器中进行调用的异步方法,其中变量str_URL
和soapRequest
分别是正确的服务地址(已检查)和格式良好的 SoapObject:
@Override
protected WebServiceResult doInBackground(Void... v) {
WebServiceResult _ret;
SoapSerializationEnvelope soapEnvelope= new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet=true;
soapEnvelope.setAddAdornments(false);
soapEnvelope.setOutputSoapObject(soapRequest);
HttpTransportSE conn = new HttpTransportSE(str_URL);
conn.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
conn.debug = true;
try {
conn.call(str_ACTION, soapEnvelope);
SoapObject o = (SoapObject)soapEnvelope.getResponse();
_ret = new WebServiceResult(o, WebServiceResultEnum.ok);
} catch (NetworkOnMainThreadException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.keskeytys);
} catch (HttpResponseException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.httpVirhe);
} catch (XmlPullParserException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.vaara_muoto);
} catch (SocketTimeoutException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.aikakatkaisu);
} catch (Exception e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.keskeytys);
}
return _ret;
}
先感谢您!
是否有可能您正在执行以下操作:
YourAsyncTask task = new YourAsyncTask();
WebServiceResult result = task.doInBackground();
因为那是错误的,完全是错误的。 如果直接调用doInBackground()
,它将在同一Thread
运行,而不是在新Thread
运行。 您需要使用execute()
启动AsyncTask
,如下所示:
YourAsyncTask task = new YourAsyncTask();
task.execute();
您需要像这样实现AsyncTask
:
public class ExampleTask extends AsyncTask<Void, Void, WebServiceResult> {
public interface FinishedListener {
public void onFinished(WebServiceResult result);
}
private final FinishedListener finishedListener;
public ExampleTask(FinishedListener listener) {
this.finishedListener = listener;
}
@Override
protected WebServiceResult doInBackground(Void... params) {
WebServiceResult result = ...;
return result;
}
@Override
protected void onPostExecute(WebServiceResult result) {
super.onPostExecute(result);
if(this.finishedListener != null) {
this.finishedListener.onFinished(result);
}
}
}
如果以这种方式实现它,则可以像这样使用它:
ExampleTask task = new ExampleTask(new ExampleTask.FinishedListener() {
@Override
public void onFinished(WebServiceResult result) {
// This will be called if the task has finished
}
});
task.execute();
似乎我在AndroidManifest.xml中声明了最低SDK为14 , 目标SDK为17 。 我没有在较新的sdk中使用任何花哨的东西,因此我将目标SDK降低到了与最低SDK 14相同的水平。我也有一个Avast! 我删除的平板电脑上运行的防病毒服务。
这解决了我的问题。 可能是Avast! 防病毒程序希望阻止来自非Play商店下载的应用程序的所有通信。 我不知道更改目标SDK是否真的有效。
嗯,我和你有同样的问题。 当它转到方法transport.call
,它会暂停,并在一段时间内引发超时问题。 一开始以为可能是网络不好,但是服务器logcat显示不是问题。 请求很好,反应很好。 我的业务流程如下:
首先,我通过子线程内部的ksoap从服务器获取一个列表,然后循环该列表,根据列表的每个项目发送一个ksoap请求。 这意味着它将发送另一个list.size()
请求。 在真机调试时出现上述问题。 我通过在获取列表并在新子线程中发出所有list.size
请求后启动一个新的子线程来解决它。 因此,在android中使用ksoap可能会导致线程阻塞,从而导致ioexception。 所以当你把它放在一个新线程中时,它会从父 catch 异常中逃脱并且工作正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.