【问题标题】:How to have a web service class to call in Async way?如何让 Web 服务类以异步方式调用?
【发布时间】:2013-10-30 09:22:55
【问题描述】:

我有一个 Web 服务类来调用我的 Web 方法。但这必须在 AsyncTask 类中调用。目前,我的所有活动中都有一个 AsyncTask 类来调用我的 Web 服务方法。是否可以将它们(Web 服务类和 AsyncTask)混合在一起,形成一个 Web 服务类,该类采用 Web 方法的名称并在执行后返回结果?

这是我的网络服务类:

package ClassLibrary;

public class WebService {
    private String namespace="";
    private String url="";

    public WebService(String namespace,String url) {
        super();
        this.namespace = namespace;
        this.url = url;
    }

    public String CallMethod(String methodName,PropertyInfo pi) {
        String result = "default";
        SoapObject request = new SoapObject(namespace, methodName);
        request.addProperty(pi);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(url);
        try {
            androidHttpTransport.call(namespace+methodName, envelope);
            SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
            result= response.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

这是我在 AsyncTask 中的访问方式:

private class AsyncCallWS extends AsyncTask<String, Void, Void> {

    private ProgressDialog dialog;
    private Activity activity;
    public String wsOutput="";
    public String methodName="";
    private WebService ws;

    public AsyncCallWS(Activity activity,String methodName) {
        this.activity = activity;
        this.dialog = new ProgressDialog(activity);
        this.methodName = methodName;
    }

    @Override
    protected Void doInBackground(String... params) {
        ws = new WebService(PublicVariable.NAMESPACE, PublicVariable.URL);
        PropertyInfo pi= new PropertyInfo();
        pi.setName("UserID");
        pi.setValue("1");
        pi.setType(String.class);
        wsOutput=ws.CallMethod("GetPersonalInfo", pi);

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        if (this.dialog.isShowing()) {
            this.dialog.dismiss();
        }

        if (methodName == "GetPersonalInfo") {
            Log.d("Ehsan","OUTPUT IS:"+ wsOutput);
        }
    }
}

【问题讨论】:

  • 而不是 AsyncTask 考虑 AsyncQueryHandler 类

标签: android web-services android-asynctask


【解决方案1】:

我建议为每个 web 服务方法添加(静态?)方法到您的 WebService 类,并从调用 Activity 传入一个侦听器,然后在 onPostExecute 中调用该侦听器。

然后您可以从您的 Activity 中调用 WebService.doThings(thingsListener),使用相应的方法执行 AsyncTask 并在提供的侦听器中对结果做出反应...

【讨论】:

    【解决方案2】:

    当我遇到同样的问题时,我做到了:

    1. 将所有 api 调用实现为static 方法。
    2. 以同步方式调用它们
    3. 一个IntentService后代,调用api然后
    4. IntentService 将结果作为意图广播。感兴趣的活动订阅此IntentService 的活动

    要使活动独立于网络操作,请考虑使用数据库、ContentProvider 或其他一些存储机制,这样可以充分利用LoaderManager 等的所有好处。这种方法会花费您一些时间,但架构将从中受益非常好。

    【讨论】:

    • 在这种情况下,最好将 ContentProvider 与 AsyncQueryHandler 结合起来,这样不仅查询会异步执行,还会更新、删除和插入
    • 您可以通过实现匿名接口来获取此信息,该接口将在doInbackground中返回结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2023-03-15
    • 2011-09-03
    相关资源
    最近更新 更多