Android调用WCFRest

来源:互联网 发布:东方财富 for mac 编辑:程序博客网 时间:2024/06/08 07:59
        最近一直处于穷忙阶段,每天下班都累的半死(项目上都是上半年松,下半年紧,估计得持续到年底,想想都累),下班感觉没精力学习了。昨天休了一天假,把Android调用WCFRest研究了下,稍作整理,例子以登录和注册为例,登录或注册后跳转新的页面显示用户信息。
        涉及到的知识点:1.WCFRest实现基础(WCFRest后面单独讲,没接触过的,就根据我的例子依葫芦画瓢,到实际要用时再研究不迟);2.Http的Get和Post请求;3.页面跳转传值;4.实体类对象与Json字符串的互转;5.子线程中通知主线程更新UI;

        1.WCFRest实现基础

        简单介绍下接口和控制台宿主配置文件。接口定义了两个方法供调用,Login方法通过Get方式调用,RegistLogin通过Post方式调用,返回值都是用户基础信息。代码如下:

[ServiceContract]public interface ILoginService{    [OperationContract(Name = "Login")]    [WebInvoke(Method = "GET",        RequestFormat = WebMessageFormat.Json,         ResponseFormat = WebMessageFormat.Json,         BodyStyle = WebMessageBodyStyle.Bare,         UriTemplate = "Login/{GID}/{PWD}")]    BaseInfo Login(string GID, string PWD);    [OperationContract(Name = "RegistLogin")]    [WebInvoke(Method = "POST",         RequestFormat = WebMessageFormat.Json,        ResponseFormat = WebMessageFormat.Json,         BodyStyle = WebMessageBodyStyle.Bare,        UriTemplate = "RegistLogin")]    BaseInfo RegistLogin(BaseInfo baseInfo);}
        宿主配置文件如下:

<?xml version="1.0"?><configuration>  <system.serviceModel>    <bindings>      <webHttpBinding>        <binding crossDomainScriptAccessEnabled="true" />      </webHttpBinding>    </bindings>    <services>      <service name="LoginService0909.LoginService">        <endpoint                  address="Http://127.0.0.1:3721/LoginService"                  binding="webHttpBinding"                  contract="LoginService0909.ILoginService"/>      </service>    </services>  </system.serviceModel></configuration>
        至于服务实现,鉴于调试的方便,数据提供模块采用了简单工厂模式加Linq To XML,实际项目一般是数据库,有兴趣的可以去深入研究相关知识。

        2.Http的Get和Post请求

        主要对象是HttpGet、HttpPost和HttpResponse三个对象,都是org.apache.http之下的;注意Post时需要设置Header的一些属性,Http的帮助类代码如下:

public class HttpHelper {public static final String BASE_URL = "http://10.0.2.2:3721/LoginService/";private static final String USER_AGENT = "Mozilla/4.5";private static HttpPost getHttpPost(String url, String json) {HttpPost request = null;try {request = new HttpPost(url);request.setHeader("Accept", "application/json");request.setHeader("Content-Type", "application/json");request.setHeader("User-Agent", USER_AGENT);} catch (IllegalArgumentException e) {System.out.println("网络调用出现异常,请检查访问的URL的书写!");return null;} catch (Exception ex) {System.out.println("网络调用出现异常,请检查网络是否开启!");return null;}if (json != null) {try {StringEntity entity = new StringEntity(json, "UTF-8");request.setEntity(entity);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return request;}public static String Post(String url, String json) {HttpPost request = HttpHelper.getHttpPost(url, json);String result = null;if (request == null) {result = "Post调用网络失败,网络有问题!";return result;}try {HttpResponse response = new DefaultHttpClient().execute(request);if (response.getStatusLine().getStatusCode() == 200) {result = EntityUtils.toString(response.getEntity());} else {result = "网络Post异常!请求失败!";}} catch (ClientProtocolException e) {result = "网络Post异常!ClientProtocolException错误!";} catch (IOException e) {e.printStackTrace();result = "网络Post异常!IOException错误!";}return result;}// 发送Get请求,获得响应查询结果public static String Get(String url) {// 获得HttpGet对象HttpGet request = null;String result = null;try {request = new HttpGet(url);} catch (IllegalArgumentException e) {result = "网络Get调用出现异常,请检查访问的URL的书写!";System.out.println(result);return result;} catch (Exception ex) {result = "网络Get调用出现异常,请检查网络是否开启!";System.out.println(result);return result;}try {HttpResponse response = new DefaultHttpClient().execute(request);if (response.getStatusLine().getStatusCode() == 200) {result = EntityUtils.toString(response.getEntity());return result;}} catch (ClientProtocolException e) {result = "网络Get异常!ClientProtocolException错误!";return result;} catch (IOException e) {result = "网络Get异常!IOException错误!";return result;}return null;}}

        3.页面跳转传值

        这个比较简单,在前面的文章也有讲过,不过要注意的,在子线程中不可执行跳转,如需跳转需要通知主线程操作跳转页面。代码如下(如果需要回传的请参考前面的文章Android之Intent):

Intent it = new Intent(MainActivity.this,UserinfoActivity.class);it.putExtra("JsonResult", txtJsonResult);MainActivity.this.startActivity(it);

        4.实体类对象与Json字符串的互转

        在Post请求时传参需要Json字符串(当然也可传入其他格式,不过Json字符串能够更广泛的用于解析对象,并且比XML更简洁),获得返回值需要将Json字符串转换为实体对象;Google提供了Gson的插件,然后将其添加进项目中去。
        对象转换成Json字符串的示例:
Gson gson = new Gson();BaseInfo baseInfo = new BaseInfo();baseInfo.GID = gidRegist.getText().toString();baseInfo.Name = nameRegist.getText().toString();baseInfo.PWD = pwdRegist.getText().toString();baseInfo.City = cityRegist.getSelectedItem().toString();String json = gson.toJson(baseInfo);//以下是Json字符串转换成对象的示例:Gson gson = new Gson();BaseInfo baseInfo = gson.fromJson(txtJsonResult, BaseInfo.class);

        5.子线程中通知主线程更新UI

        在主线程中定义一个Handle对象,代码如下:

Handler handlerUserInfo = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 0://这边写更新UI的操作break;}}};
        然后在子线程中要更新UI的地方写上:

handlerUserInfo.sendEmptyMessage(0);
        这里参数0就是上面的msg.What,主线程用来判断执行相应的代码;

        6.运行效果截图




        注:本机调试时只要将WCFRest的解决方案直接运行即可,然后运行Android的模拟器就可以了。如果要在手机上调试,需要将WCFRest的服务地址改成你本机的ip地址再运行,然后在Android中的HttpHelper将ip地址改成电脑的ip地址,我用手机测试时手机连的是电脑开的Wifi,测试通过。

        7.其它犯的一些错误:

            1.页面需在AndroidManifest.xml注册;
            2.网络权限需在AndroidManifest.xml注册;
            3.Post请求时注意Url最后不要加/了;
               错误元凶:String url = HttpHelper.BASE_URL + "RegistLogin";
               当时在RegistLogin后面又加了一个/导致出错,花了不少时间找这个错误;
            4.子线程中也是不能跳转页面的,要通知主线程操作跳转页面;
            5.页面的对象在定义后别忘了实例化;
               错误元凶:TextView gidRegist = null;
               定义后没有实例化,然后取值时报错;这个错误好找,但也要有耐心看那英文错误;
            6.最后一个就是本地ip地址啦(这个没出错,友情提醒一下),
               计算机本地地址是127.0.0.1而对应的Android本地是10.0.2.2;


        至此全部完成,只是个人的一些实践,对自己是一个记录,同时希望也能对别人有些帮助,如果有什么错误,还望不吝指出,共同进步,转载请保留原文地址。

        源码下载


0 0
原创粉丝点击