Android上的KSoap2冻结设备而不是进行Web服务调用

时间:2014-07-29 14:33:42

标签: java android ksoap2 android-ksoap2

我正在尝试连接到我为接收来自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_URLsoapRequest分别是正确的服务地址(已检查)和格式良好的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;
}

提前谢谢!

2 个答案:

答案 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是否真的有很大影响。