我正在尝试连接到我为接收来自Android设备的SOAP调用而创建的 .NET 4.0 webservice,现在托管在本地IIS 上用于测试目的。< / p>
我发现 ksoap2 是一个出色的类库,可以用来做我想做的事情。从https://code.google.com/p/ksoap2-android/下载了.jar软件包,然后开始用手指敲击键盘。
发送的信息量从几千字节到几兆字节。
HttpTransportSE.call(String, SoapSerializationEnvelope)
- 方法在Eclipse的Android模拟器中完美运行,将调用发送到托管在本地IIS中的webservice。甚至测试过webservice在尝试从同一局域网中的Web浏览器打开服务地址时收到空呼叫。
当我将.apk文件复制到Android设备时,安装它,启动它并尝试拨打电话,整个程序冻结而不拨打电话。
正如您在代码块中看到的那样,在可能的错误被考虑之后会出现一些行:在模拟环境中,成功的调用会返回 SoapPrimitive - 对象或流入正确的 catch block 根据当前情况为用户生成错误消息。
然后在现场Android设备上,程序会永远失去它的响应能力,并且必须从应用程序菜单中终止。
我从异步方法中删除了调用,并尝试直接从为按钮点击事件分配的匿名内部函数中调用它。
试图不打算回复,只是打电话。
尝试获取设备的logcat程序,看看UI背后发生了什么,发现两个,他们需要root访问权限,这是我在设备中没有的。这就是为什么我没有任何记录显示你,并显示模拟器logcat可能(?)是无用的,因为它在那里工作正常。
不尝试连接到localhost。
尝试在运行 Android 4.2.2 的旧版Lenovo平板电脑上安装程序,并在全新的三星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;
}
提前谢谢!
答案 0 :(得分:0)
你有可能做这样的事情:
YourAsyncTask task = new YourAsyncTask();
WebServiceResult result = task.doInBackground();
因为那是错误的,完全错误的。如果您直接致电doInBackground()
,它将在同一个Thread
中运行,而不是在新的AsyncTask
中运行。您需要以execute()
开头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();
如果你以这种方式实现它,你可以像这样使用它:
{{1}}
答案 1 :(得分:0)
似乎我已在 AndroidManifest.xml 中声明最低SDK为14 且目标SDK为17 。我没有在较新的sdk中使用任何花哨的东西,所以我将目标SDK降低到与最小SDK,14相同的水平。我还有一个 Avast!我删除的平板电脑上运行的防病毒服务。
这解决了我的问题。可能是Avast!防病毒程序希望阻止未从Play商店下载的应用程序的所有通信。我不知道改变目标SDK是否真的有很大影响。