我们在平常的开发中,对网络的操作用到HTTP协议比较多,通过我们使用Get或者Post的方法调用一个数据接口,然后服务器给我们返回JSON格式的数据,我们解析JSON数据然后展现给用户,相信很多人很喜欢服务器给我们返回JSON数据格式,因为他解析方便,也有一些JSON的解析库,例如Google提供的GSON
不过有时候我们用到WebService接口来获取数据(最近我就遇到了需要使用WebService接口来提交并获取数据), WebService是一种基于SOAP协议的远程调用标准,通过webservice可以将不同操作系统平台、不同语言、不同技术整合到一块。在Android SDK中并没有提供调用WebService的库,因此,需要使用第三方的SDK来调用WebService。PC版本的WEbservice客户端库非常丰富,例如Axis2,CXF等,但这些开发包对于Android系统过于庞大,也未必很容易移植到Android系统中。因此,这些开发包并不是在我们的考虑范围内。适合手机的WebService客户端的SDK有一些,比较常用的有Ksoap2,可以点击这里下载,下载完后将jar包加入到libs目录下 Add as Library就行了,接下来我们就来看下怎样来调用WebService接口 。
我们可以从http://www.webxml.com.cn/zh_cn/web_services.aspx来获取WebService接口,这里面有一些免费的WebService接口,我们就用里面的天气接口吧http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
首先我们新建一个WebService的工具类WebServiceUtils ,用于对WebService接口的调用,以后遇到调用WebService直接拷贝来用就行了
package com.test.wjy.statusbartest.WebService;
import android.os.Handler;
import android.os.Message;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 访问WebService的工具类
* Created by wjy on 2017/5/10.
*/
public class WebServiceUtils {
public static final String WEB_SERVER_URL = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx";
// 含有3个线程的线程池
private static final ExecutorService executorService = Executors.newFixedThreadPool(3);//限制线程池大小为3的线程池
// 命名空间
private static final String NAMESPACE = "http://WebXml.com.cn/";
public static void callWebService(String url, final String methodName, HashMap<String,String> properties,final WebServiceCallBack webServiceCallBack){
//创建HttpTransportSE对象,传递WebService服务器地址
final HttpTransportSE httpTransportSE = new HttpTransportSE(url);
//创建SoapObject对象
final SoapObject soapObject = new SoapObject(NAMESPACE,methodName);
//SoapObject添加参数
if (properties != null){
for (Iterator<Map.Entry<String,String>> it = properties.entrySet().iterator();it.hasNext();){
Map.Entry<String,String> entry = it.next();
soapObject.addProperty(entry.getKey(),entry.getValue());
}
}
//实例化SoapSerializationEnvelope,传入WebService的SOAP协议的版本号
final SoapSerializationEnvelope soapSerializationEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//设置是否调用的是.NET开发的WebService
soapSerializationEnvelope.setOutputSoapObject(soapObject);
soapSerializationEnvelope.dotNet = true;
httpTransportSE.debug = true;
//用于子线程与主线程通信的Handler
final Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//将返回值回调到callBack的参数中
webServiceCallBack.callBack((SoapObject) msg.obj);
}
};
//开启线程去访问WebService
executorService.submit(new Runnable() {
@Override
public void run() {
SoapObject resultSoapObject = null;
try {
httpTransportSE.call(NAMESPACE + methodName,soapSerializationEnvelope);
if (soapSerializationEnvelope.getResponse() != null){
//获取服务器响应返回的SoapObject
resultSoapObject = (SoapObject) soapSerializationEnvelope.bodyIn;
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}finally {
//将获取的消息通过handler发到主线程
mHandler.sendMessage(mHandler.obtainMessage(0,resultSoapObject));
}
}
});
}
public interface WebServiceCallBack{
public void callBack(SoapObject result);
}
}
接下来就是我们在Activity中实现获取省份(只拿这一个为例),先用工具类调用WebService方法,然后在回调方法callBack(SoapObject result)中解析数据到一个List中,在设置ListView的适配器,具体代码如下:
package com.test.wjy.statusbartest.WebService;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.test.wjy.statusbartest.R;
import org.ksoap2.serialization.SoapObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by wjy on 2017/5/10.
*/
public class WebServiceConnActivity extends Activity {
private List<String> provinceList = new ArrayList<String>();
@Bind(R.id.tv_result)
TextView tvResult;
@Bind(R.id.province_list)
ListView lv_provinceList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webserviceconn);
ButterKnife.bind(this);
initConn();
}
private void initConn() {
HashMap<String, String> properties = new HashMap<String, String>();
// properties.put("theCityName", "深圳");
//如果有请求字段则写properties,否则将properties至为null即可
WebServiceUtils.callWebService(WebServiceUtils.WEB_SERVER_URL, "getSupportProvince", properties, new WebServiceUtils.WebServiceCallBack() {
@Override
public void callBack(SoapObject result) {
if (result != null) {
tvResult.setText("result:" + result+"\n解析结果如下:");
Log.e("cacacaca", "result:" + result);
provinceList = parseSoapObject(result);
lv_provinceList.setAdapter(new ArrayAdapter<String>(WebServiceConnActivity.this, android.R.layout.simple_list_item_1, provinceList));
} else {
Toast.makeText(WebServiceConnActivity.this, "获取WebServicce数据失败", Toast.LENGTH_SHORT).show();
}
}
});
}
/**
* 解析SoapObject对象
* @param result
* @return
*/
private List<String> parseSoapObject(SoapObject result){
List<String> list = new ArrayList<String>();
SoapObject provinceSoapObject = (SoapObject) result.getProperty("getSupportProvinceResult");
if(provinceSoapObject == null) {
return null;
}
for(int i=0; i<provinceSoapObject.getPropertyCount(); i++){
list.add(provinceSoapObject.getProperty(i).toString());
}
return list;
}
}
简单的XML布局代码,如下布局会在页面上显示返回的原始数据以及解析后的数据展示在列表里
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="result:"/>
<ListView
android:id="@+id/province_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="@android:color/transparent"
android:fadingEdge="none" >
</ListView>
</LinearLayout>
下面附上一张运行结果的效果图
这样在Android开发中通过WebService调用接口,请求以及返回数据并解析就完成了,有疑问的朋友请在下面留言,有不足之处也希望大家多多指教,谢谢!