Android访问webservice

这篇博客主要介绍了Android开发中访问WebService的方法,包括使用Ksoap2和HttpUrlConnection的详细步骤。提供了相关工具类和资源下载链接,以及一篇讲解较好的参考文章。

Android开发中很多时候要用到webservice,这样可以方便的访问网络资源,这里提供几个网站:

阿里巴巴的FastJson介绍:http://code.alibabatech.com/wiki/display/FastJSON/Home

适合手机的WebService的SDK:Ksoap2:https://code.google.com/archive/p/ksoap2-android/wikis/HowToUse.wiki

获取WebService:http://www.webxml.com.cn/zh_cn/web_services.aspx


这里测试使用天气接口:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx

一、使用Ksoap2:

工具类:WebServiceUtils.java(这个工具类以后就可以直接拿来使用了)

package com.mfc.UrlUtils;

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;

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 android.os.Handler;
import android.os.Message;

/*
 * 访问WebService的工具类
 * 2017年8月10日13:05:29
 * */
public class WebServiceUtils {
	//webservice路径
	public static final String WEB_SERVICE_URL = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx";
	//命名空间
	//这个命名空间:找到webservice的网页,点击WSDL就会看到xml,里面有一个
	//<wsdl:definitions targetNamespace="http://WebXml.com.cn/">
	//就是这个命名空间
	private static final String NAMESPACE = "http://WebXml.com.cn/";

	//含有三个线程的线程池
	private static final ExecutorService executorService = Executors.newFixedThreadPool(3);

	/**
	 *
	 * @param url
	 *            WebService服务器地址
	 * @param methodName
	 *            WebService的调用方法名
	 * @param properties
	 *            WebService的参数
	 * @param webServiceCallBack
	 *            回调接口
	 */
	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对象
		SoapObject soapObject = new SoapObject(NAMESPACE, methodName);
		//soapObject添加参数,这里通过传过来一个HashMap来设置参数
		if(properties != null){
			Iterator<Map.Entry<String, String>> it = properties.entrySet().iterator();
			while(it.hasNext()){
				Map.Entry<String, String> entry = it.next();
				soapObject.addProperty(entry.getKey(),entry.getValue());
			}
		}
		//实例化SoapSerializationEnvelope,传入WebService的SOAP协议的版本号
		final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		//设置是否调用的是.Net开发的WebService
		soapEnvelope.setOutputSoapObject(soapObject);
		soapEnvelope.dotNet = true;
		httpTransportSE.debug = true;

		//用于子线程与主线程通信的Handler
		final Handler handler = 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, soapEnvelope);
					if(soapEnvelope.getResponse() != null){
						//获取服务器响应返回的SoapObject
						resultSoapObject = (SoapObject) soapEnvelope.bodyIn;
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (XmlPullParserException e) {
					e.printStackTrace();
				} finally {
					//将获取的消息利用handler发送到主线程
					handler.sendMessage(handler.obtainMessage(0, resultSoapObject));
				}

			}
		});


	}

	public interface WebServiceCallBack {
		public void callBack(SoapObject result);
	}
}

获取省份的activity:

package com.example.administrator.webserviceandhttpurl;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.widget.AdapterView.OnItemClickListener;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.mfc.UrlUtils.WebServiceUtils;

import org.ksoap2.serialization.SoapObject;

import java.util.ArrayList;
import java.util.List;

public class KsoapProvinceActivity extends AppCompatActivity {
    private List<String> provinceList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.provinceandcity);
        init();
    }

    private void init(){
        final ListView listView = (ListView) findViewById(R.id.provinceAndCity);
        //显示进度条
        final ProgressDialog dialog;
        dialog = ProgressDialog.show(KsoapProvinceActivity.this, "提示", "加载中,请稍后...");

        //通过工具类调用WebService接口
        WebServiceUtils.callWebSerVice(WebServiceUtils.WEB_SERVICE_URL, "getSupportProvince", null, new WebServiceUtils.WebServiceCallBack() {

            //WebService接口返回的数据回调到这个方法中
            @Override
            public void callBack(SoapObject result) {
                //关闭进度条
                dialog.dismiss();
                if(result != null){
                    provinceList = parseSoapObject(result);
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(KsoapProvinceActivity.this, android.R.layout.simple_list_item_1,provinceList);
                    listView.setAdapter(adapter);

                }else{
                    Toast.makeText(KsoapProvinceActivity.this, "获取WebService数据错误", Toast.LENGTH_SHORT).show();
                }

            }
        });

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(KsoapProvinceActivity.this, KsoapCityActivity.class);
                intent.putExtra("province", provinceList.get(position));
                startActivity(intent);
            }
        });

    }

    //解析SoapObject对象
    private List<String> parseSoapObject(SoapObject result){
        List<String> list = new ArrayList<String>();
        //返回的属性中有getSupportProvinceResult,返回的值可能还是一个SoapObject对象,那就再调用一次这个方法,总能得到想要的值
        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;
    }
}

获取城市的Activity:

package com.example.administrator.webserviceandhttpurl;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.ksoap2.serialization.SoapObject;

import android.app.ProgressDialog;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.mfc.UrlUtils.WebServiceUtils;

public class KsoapCityActivity extends AppCompatActivity {
    private List<String> cityStringList = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.provinceandcity);
        init();
    }
    private void init() {
        final ListView listView = (ListView) findViewById(R.id.provinceAndCity);
        // 显示进度条
        final ProgressDialog dialog;
        dialog = ProgressDialog.show(KsoapCityActivity.this, "提示", "加载中,请稍后...");

        // 添加参数
        HashMap<String, String> properties = new HashMap<String, String>();
        properties
                .put("byProvinceName", getIntent().getStringExtra("province"));
        // 通过工具类调用WebService接口
        WebServiceUtils.callWebSerVice(WebServiceUtils.WEB_SERVICE_URL,
                "getSupportCity", properties, new WebServiceUtils.WebServiceCallBack() {

                    // WebService接口返回的数据回调到这个方法中
                    @Override
                    public void callBack(SoapObject result) {
                        // 关闭进度条
                        dialog.dismiss();
                        if (result != null) {
                            cityStringList = parseSoapObject(result);
                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                                    KsoapCityActivity.this,
                                    android.R.layout.simple_list_item_1,
                                    cityStringList);
                            listView.setAdapter(adapter);

                        } else {
                            Toast.makeText(KsoapCityActivity.this,
                                    "获取WebService数据错误", Toast.LENGTH_SHORT)
                                    .show();
                        }

                    }
                });

        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                                    int arg2, long arg3) {
                Intent intent = new Intent(KsoapCityActivity.this, KsoapWeatherActivity.class);
                intent.putExtra("city", cityStringList.get(arg2));
                startActivity(intent);

            }
        });
    }

    // 解析SoapObject对象
    private List<String> parseSoapObject(SoapObject result) {
        List<String> list = new ArrayList<String>();
        SoapObject provinceSoapObject = (SoapObject) result
                .getProperty("getSupportCityResult");
        for (int i = 0; i < provinceSoapObject.getPropertyCount(); i++) {
            String cityString = provinceSoapObject.getProperty(i).toString();
            list.add(cityString.substring(0, cityString.indexOf("(")).trim());
        }

        return list;
    }
}

显示省份和城市用的是一个xml:provinceandcity.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">

    <ListView
        android:id="@+id/provinceAndCity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></ListView>
</LinearLayout>

获取天气信息的Activity:

package com.example.administrator.webserviceandhttpurl;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.HashMap;

import org.ksoap2.serialization.SoapObject;

import android.app.ProgressDialog;
import android.widget.TextView;
import android.widget.Toast;

import com.mfc.UrlUtils.WebServiceUtils;

public class KsoapWeatherActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.weather);
        init();
    }

    private void init() {
        final TextView mTextWeather = (TextView) findViewById(R.id.weather);
        // 显示进度条
        final ProgressDialog dialog;
        dialog = ProgressDialog.show(KsoapWeatherActivity.this, "提示", "加载中,请稍后...");
        HashMap<String, String> properties = new HashMap<String, String>();
        properties.put("theCityName", getIntent().getStringExtra("city"));

        WebServiceUtils.callWebSerVice(WebServiceUtils.WEB_SERVICE_URL,
                "getWeatherbyCityName", properties, new WebServiceUtils.WebServiceCallBack() {

                    @Override
                    public void callBack(SoapObject result) {
                        dialog.dismiss();
                        if (result != null) {
                            SoapObject detail = (SoapObject) result
                                    .getProperty("getWeatherbyCityNameResult");
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < detail.getPropertyCount(); i++) {
                                sb.append(detail.getProperty(i)).append("\r\n");
                            }
                            mTextWeather.setText(sb.toString());
                        } else {
                            Toast.makeText(KsoapWeatherActivity.this,
                                    "获取WebService数据错误", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }
                });
    }
}

显示天气的xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ScrollView  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent" >  
  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="match_parent" >  
  
            <TextView  
                android:id="@+id/weather"  
                android:textColor="#336598"  
                android:textSize="16sp"  
                android:layout_width="match_parent"  
                android:layout_height="match_parent" />  
        </LinearLayout>  
    </ScrollView>  

</RelativeLayout>

效果图(这里不知道为什么显示不出来天气,还望有人指点):


二、使用HttpUrlConnection:

工具类:

package com.mfc.UrlUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Administrator on 2017/8/10.
 */

public class HttpURLConnectionUtils {

    public static String getRemoteInfo(String targetUrl){
        String jsonString="";
        try {
            URL url=new URL(targetUrl);
            HttpURLConnection connection=(HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            int code=connection.getResponseCode();
            if(code==200){
                InputStream inputStream=connection.getInputStream();
                ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
                int len=0;
                byte[] data=new byte[1024];
                while ((len=inputStream.read(data))!=-1) {
                    outputStream.write(data, 0, len);
                }
                jsonString=new String(outputStream.toByteArray());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return jsonString;
    }
}

Activity:

package com.example.administrator.webserviceandhttpurl;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.mfc.UrlUtils.HttpURLConnectionUtils;

/*
* 以查询湖北省的所有城市名称为例
* */
public class HttpURLConnectionActivity extends AppCompatActivity {
    private String allCityString;
    private TextView allcity;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 000:
                    allcity.setText(filterHtml(allCityString));
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.allcity);
        allcity = (TextView) findViewById(R.id.allcity);
        init();
    }

    private void init(){
        final String path="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=随州";
        new Thread(new Runnable() {
            @Override
            public void run() {
                allCityString = HttpURLConnectionUtils.getRemoteInfo(path);
                handler.sendEmptyMessage(000);
            }
        }).start();
    }

    /**
     * 使用正则表达式过滤HTML标记
     *
     * @param source 待过滤内容
     * @return
     */
    private String filterHtml(String source) {
        if(null == source){
            return "";
        }
        return source.replaceAll("</?[^>]+>","").trim();
    }
}

显示界面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">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/allcity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </ScrollView>


</LinearLayout>

效果图:


资源下载:http://download.youkuaiyun.com/download/fancheng614/9928559

找了比较多类似的博客,发现这一篇讲的挺好的:http://blog.youkuaiyun.com/lyq8479/article/details/6428288



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值