上一篇,我们简单的讲述了Android如何进行WebService调用!

而往往我们在项目中会先封装一下再使用!那么我们如何进行能力封装使用呢?

一.了解共性,机制,思考可扩展,独立,可移植性。

首先在Android中通讯,我们必不可少的那便是Handler,Thread。

由于Android的机制,我们需要考虑

  1. UI线程不能处理耗时操作,显然通讯属于耗时操作。所以我们用到Thread

  2. 子线程不能更新UI线程,所以我们需要用Handler机制来通知UI线程做出反应

由于服务器语种我们需要考虑

目前主要用2种语言开发的WebService Java和.net

结合上述的考虑,那么大致的思路是不有点眉目了!

试着写写吧!

首先创建一个类WebService

基本上请求有开始,正在请求,发生错误,成功,结束请求5种状态

我们便添加Handler处理消息的类别甄别,当然这里可以直接定义,而我这里是定一个内部类作为甄别类。

 class MsgCode {
        public final static int STATR = 0x01; //开始
        public final static int ERROR = 0x02; //错误
        public final static int SUSSCE = 0x03;//成功
        public final static int FINALY = 0x04;//结束
        public final static int PROGRESS = 0x05;//正在请求中
    }

接下来我们想想我们WebService请求一般来说需要哪些参数,罗列一下我们需要下面6类。

  1. 服务器URL

  2. 命名空间URL

  3. 请求的函数名称

  4. 请求的参数列表

  5. 请求的服务器类别

  6. Handler处理消息对象

罗列完毕,那我们的思路便更加明确了。这时候我们建立一个start函数,这里请求参数列表用Map便让key value的形式完全和webservice的参数形式对应了。

public static void start(final String sv_url, final String ns_url,
            final String mthd, final HashMap<String, Object> params,
            final boolean isdotnet, final Handler callback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
              //webservice调用处理方法
            }
        }).start();

    }

现在来让我们具体用代码回顾一下上一篇文章讲的

Android如何进行WebService调用,我们定义一个调用的具体函数start_函数,参数与start相同。

static void start_(String serviceUrl, String namespaceUrl,
            String serviceMethod, HashMap<String, Object> params,
            boolean isDotNet, Handler handler) {
            }

接下来我们一步一步的回顾一下上一篇讲的如何调用

//构建SoapSerializationEnvelope
SoapSerializationEnvelope evlp = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);//对应于Ksoap 1.1规范
//构建SoapObject 
SoapObject soapobject = new SoapObject(namespaceUrl, serviceMethod);
//构建传输的参数列表
//设置SoapObject 
evlp.bodyOut = soapobject; 
//你也可以如此
evlp.setOutputSoapObject(soapobject);
//设置是否为.net
evlp.dotNet = isDotNet;
//这里有个timeout超时我们可以定义一个在类里面定义静态常量50s作为超时时间可根据需要修改
private static int timeout = 1000 * 50;
HttpTransportSE hts = new HttpTransportSE(serviceUrl, timeout);
//调用        注意,这里有个actionUrl是namespaceUrl+serviceMethod的结果,
//一般是服务器?wsdl 里面的targetNamespace+ 函数name
hts.call(actionUrl, evlp);
//接收结果
Object result = evlp.getResponse();
//或者
Object result =  evlp.bodyIn;

当然上面的代码直接copy过去是不能直接用的我们仔细想想,我们缺了哪些!

首先我们缺了构建参数列表好!下面我创建一个addParam函数通过遍历HashMap来添加参数列表

private static void addParam(SoapObject soapobject,
            HashMap<String, Object> params) {
        // TODO Auto-generated method stub
        if (params != null && !params.isEmpty()) {
            Iterator iter = params.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object val = entry.getValue();
                PropertyInfo pi = new PropertyInfo();
                pi.setName(key.toString());
                pi.setValue(val);
                pi.setType(val.getClass());
                soapobject.addProperty(pi);
                //当然你如果只传字符串直接上面PropertyInfo pi = new PropertyInfo();
                //以后的注释掉直接用下面的也行
                // soapobject.addProperty(key.toString(), val.toString());
            }
        }
    }
//构建传输的参数列表处加上下面的语句
addParam(soapobject, params);

让我们再看看少了些什么?

对我们少了handler机制处理,来让我们加上!start_函数就变成下面这个样子

/**
     * 调用的具体函数
     * 
     * @param serviceUrl
     * @param namespaceUrl
     * @param serviceMethod
     * @param params
     * @param isDotNet
     * @param handler
     */
    static void start_(String serviceUrl, String namespaceUrl,
            String serviceMethod, HashMap<String, Object> params,
            boolean isDotNet, Handler handler) {
        // TODO Auto-generated method stub
        String actionUrl = namespaceUrl + serviceMethod;
        handler.obtainMessage(MsgCode.STATR).sendToTarget();
        SoapObject soapobject = new SoapObject(namespaceUrl, serviceMethod);
        addParam(soapobject, params);
        SoapSerializationEnvelope evlp = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        evlp.bodyOut = soapobject;
        evlp.dotNet = isDotNet;
        evlp.setOutputSoapObject(soapobject);
        HttpTransportSE hts = new HttpTransportSE(serviceUrl, timeout);
        try {
            hts.call(actionUrl, evlp);
            Object result = evlp.getResponse();
            if (result.getClass().isAssignableFrom(SoapFault.class)) {
                handler.obtainMessage(MsgCode.ERROR, result).sendToTarget();
            } else {
                handler.obtainMessage(MsgCode.SUSSCE, result).sendToTarget();
            }
        } catch (HttpResponseException e) {
            // TODO Auto-generated catch block
            handler.obtainMessage(MsgCode.ERROR, e.getMessage()).sendToTarget();
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            handler.obtainMessage(MsgCode.ERROR, e.getMessage()).sendToTarget();
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            // TODO Auto-generated catch block
            handler.obtainMessage(MsgCode.ERROR, e.getMessage()).sendToTarget();
            e.printStackTrace();
        }
        handler.obtainMessage(MsgCode.FINALY).sendToTarget();
    }

这样我们一个完整的请求WebService类就构建完毕了!

这篇文章的内容也就结束了!

这时候用的朋友会发现一个问题。我们这个如果要传对象,我们该如何处理呢?

好的请大家接下来请期待下一篇文章《Android调用WebService系列之对象构建传递》