补充:关于PHP服务端可能出现的问题:

如果你刚好也像我一样,用php实现的服务端程序,采用的是apache服务器,那么虚拟主机的配置可能会影响到android应用的调试!!

在android应用中访问的IP都是10.0.2.2,如果在apache虚拟主机配置文件中配置了多个虚拟主机,那么将默认解析为对第一个虚拟主机的请求,所以,在调试android应用时,应该将对应的服务端所配置的那个虚拟主机放在配置文件中的第一个虚拟主机的位置。否则就会出现请求的文件不存在等的错误。

服务端返回JSON数据及在android应用中解析JSON数据

1.新建一个json.php文件,返回json格式的数据

 <?php

 if(isset($_REQUEST["username"])&& isset($_REQUEST["password"])){

       $username = $_REQUEST["username"];

       $password = $_REQUEST["password"];

       if($username == "zhangsan" && $password == "123"){

            $arr = array(

                       "errorCode"=>200,

                       "errorMsg"=>"login success"

            );

            echo json_encode($arr);

       }else{

            $arr = array(

                       "errorCode"=>404,

                       "errorMsg"=>"login failure"

            );

            echo json_encode($arr);

       }

 }else{

       $arr = array(

                       "errorCode"=>500,

                       "errorMsg"=>"illeagle params"

            );

       echo json_encode($arr);

 }

 ?>

返回的信息格式如下:

{"errorCode":500,"errorMsg":"illeagle params"}

一个大括号内的表示的是一个json对象,内部存储的是键值对数据,键与值用冒号分隔,多个键值对之间用逗号分隔。

形式如同下面格式的是json array对象:

[{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"}]

中括号里面存放的是用逗号分隔的一个个json对象。

2.Android中要解析json格式数据需要用到的类有JSONObject和JSONArray

JSONObject直接使用传入字符串形式的参数的构造方法创建JSONObject实例,然后调用相应的get方法,即可获取json形式数据中的每个键对应的值。

当返回的数据是用中括号括着的多个json形式字符串是,就要用到JSONArray了,同样可以使用字符串参数构造出JSONArray实例,然后可以使用下标的形式获取到其中的每一个JSONObject对象,然后使用JSONObject的方法分别取解析即可。

简单使用示例:

在MainActivity中添加上修改Handler的消息处理方法,当前通过get或者post取得的是json格式的数据,所以添加上对json数据的解析:

 private Handler handler = new Handler(){

            public void handleMessage(android.os.Message msg) {

                  if(msg.what == OK){

                       String str = msg.obj.toString();

                       try {

                             JSONObject obj = new JSONObject(str);

                             Log.i(TAG,obj.getString("errorCode"));

                             Log.i(TAG,obj.getString("errorMsg"));

                       } catch (JSONException e) {

                             // TODO Auto-generated catch block

                             e.printStackTrace();

                       }

                  }

            }

 };

运行结果:

有时候,服务端返回的可能是一些实体类信息,若用户登录成功,返回存放用户个人信息用以缓存在本地,这时,可能希望直接能将返回的JSON格式的数据解析为实体类对象,以简化操作。使用JSONObject类当然也能实现,只要获取到各个字段的值,然后通过它们构造实体类对象即可。但是,还有更简单的方式,那就是使用GSON。

3.使用GSON解析json数据

要在自己项目中使用GSON,有两种方式:

方式1:从网上下载gson的jar包,放到项目的libs目录中,然后添加到项目的build path中,就可以直接使用GSON了

方式2:下载GSON的源码,可以到github上下载,然后把源码整个复制到src目录下,之后也可以直接使用GSON了。

下面是GSON的简单使用示例,更多的使用可以参考GSON的帮助文档:在下载源码的包中有docs目录,里面就是GSON使用的帮助文档,可以在需要时参考。

新建一个实体类,存放返回的errorCode和errorMsg:

 package cn.csc.start.bean;

 public class ResponseInfo {

       private int errorCode;

       private String errorMsg;

       public int getErrorCode() {

            return errorCode;

       }

       public void setErrorCode(int errorCode) {

            this.errorCode = errorCode;

       }

       public String getErrorMsg() {

            return errorMsg;

       }

       public void setErrorMsg(String errorMsg) {

            this.errorMsg = errorMsg;

       }

       public ResponseInfo(int errorCode, String errorMsg) {

            super();

            this.errorCode = errorCode;

            this.errorMsg = errorMsg;

       }

       public ResponseInfo() {

            super();

       }

 }

修改Handler中消息处理中解析json数据的代码,这次改用GSON方式解析:

 Gson gson = new Gson();

 ResponseInfo info = gson.fromJson(str, ResponseInfo.class);

 Toast.makeText(MainActivity.this, info.getErrorCode()+info.getErrorMsg(), Toast.LENGTH_LONG).show();

注意到,使用GSON的方式解析到实体类对象非常简单:

没有特别的需求时,使用默认构造创建GSON实例即可,需要特殊的配置时,可以使用GsonBuilder来创建GSON实例,具体参考说明文档

调用fromJson()传入要解析的数据,及解析后的对象类型,即可完成从json格式字符串到实体类对象的解析。

若是json array形式的字符串,解析则稍微麻烦一点:

如:想要解析[{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"}]为List<ResponseInfo>

但是不能List<ResponseInfo>.class,这时GSON中提供了获取泛型的类型信息的方法:

使用TypeToken

TypeToken< List<ResponseInfo>> list = new TypeToken< List<ResponseInfo>>() {};

然后调用list.getType()注意返回的是Type类型的对象,而Gson的fromJson()方法刚好有第二个参数为Type类型的重载形式。

所以,对[{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"},{"errorCode":200,"errorMsg":"login success"}]解析的具体代码如下:

 Gson gson = new Gson();

 TypeToken<List<ResponseInfo>> list = new TypeToken<List<ResponseInfo>>(){};

 List<ResponseInfo> info_list = gson.fromJson(str, list.getType());

以上,就是两种对json形式数据的解析方式。

与服务器交互的方式除了内置的HttpURLConnection和HttpClient之外,还可以选择一些优秀的开源项目,来简化与服务端交互的工作,如使用AsyncHttpClient

AsyncHttpClient可以到github上获取:

在github中搜说async-http即可找到该项目,然后clone或者下载zip包就可以获得该项目了。

在自己的项目中使用async-http的方式如同GSON,也可以直接使用源码,或者引用jar包,根据个人喜好即可。

简单演示下async-http发送get和post请求的示例:

在MainActivity中添加两个方法:

使用AsyncHttpClient发送get请求

 private void async_get_test(){

            String username = et_username.getText().toString();

            String password = et_password.getText().toString();

            AsyncHttpClient client = new AsyncHttpClient();

            client.get("http://10.0.2.2/index.php?username="+username+"&password="+password, new AsyncHttpResponseHandler() {

                  @Override

                  public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                       // TODO Auto-generated method stub

                       Message msg = new Message();

                       msg.what = OK;

                       msg.obj = new String(responseBody);

                       handler.sendMessage(msg);

                  }

                  @Override

                  public void onFailure(int statusCode, Header[] headers,

                             byte[] responseBody, Throwable error) {

                       // TODO Auto-generated method stub

                       Message msg = new Message();

                       msg.what = OK;

                       msg.obj = new String(responseBody);

                       handler.sendMessage(msg);

                  }

            });

       }

使用AsyncHttpClient发送post请求

 private void async_post_test(){

            String username = et_username.getText().toString();

            String password = et_password.getText().toString();

            AsyncHttpClient client = new AsyncHttpClient();

            RequestParams params = new RequestParams();

            params.add("username", username);

            params.add("password", password);

            client.post("http://10.0.2.2/index.php", params , new AsyncHttpResponseHandler() {

                  @Override

                  public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                       // TODO Auto-generated method stub

                       Message msg = new Message();

                       msg.what = OK;

                       msg.obj = new String(responseBody);

                       handler.sendMessage(msg);

                  }

                  @Override

                  public void onFailure(int statusCode, Header[] headers,

                             byte[] responseBody, Throwable error) {

                       // TODO Auto-generated method stub

                       Message msg = new Message();

                       msg.what = OK;

                       msg.obj = new String(responseBody);

                       handler.sendMessage(msg);

                  }

            });

 }

可以看到使用AsyncHttpClient的方式非常简单:

get方式:

创建AsyncHttpClient对象,然后调用get方法即可。

唯一稍微复杂的就是get方法的第二个参数:AsyncHttpResponseHandler,需要创建一个匿名内部类对象,然后重写AsyncHttpResponseHandler的两个方法,分别是网络请求成功的回调方法及网络请求失败的回调方法。

post方式:

就比get方式多了一个传递参数而已:

RequestParams params = new RequestParams();

params.add("username", username);

params.add("password", password);

使用RequestParams对象存放要提交的参数,然后将其传递给post()方法即可。

android菜鸟学习笔记25----与服务器端交互(二)解析服务端返回的json数据及使用一个开源组件请求服务端数据的更多相关文章

  1. android菜鸟学习笔记24----与服务器端交互(一)使用HttpURLConnection和HttpClient请求服务端数据

    主要是基于HTTP协议与服务端进行交互. 涉及到的类和接口有:URL.HttpURLConnection.HttpClient等 URL: 使用一个String类型的url构造一个URL对象,如: U ...

  2. android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人

    要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上 ...

  3. android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

    ContentProvider是Android四大组件之一,它用来封装数据,并通过ContentResolver接口将数据提供给其他应用.只有当需要在多个应用之间共享数据时才会用到ContentPro ...

  4. android菜鸟学习笔记20----Android数据存储(四))Android数据库操作

    Android内置了一个名为SQLite的关系型数据库,这是一款轻量型的数据库,操作十分简便.SQLite与别的数据库不同的是,它没有数据类型.可以保存任何类型的数据到你所想要保存的任何表的任何列中. ...

  5. android菜鸟学习笔记28----Android中的Service生命周期及本地和远程服务绑定的实现

    Service是Android中长期在后台运行的没有界面的组件,使用服务的优势在于:能够提高进程的优先级,系统不容易回收掉进程,即便回收了,内存充足的时候,会把进程重新创建. 1.服务的简单使用示例: ...

  6. android菜鸟学习笔记14----Android控件(三) ListView的简单使用

    MVC模式: MVC的基本原理就是通过Controller连接View和Model.当View中所显示的数据发生变化时,会通知Controller,然后由Controller调用Model中的相关方法 ...

  7. android菜鸟学习笔记6----android布局(一)

    Android应用的UI组件都是继承自View类,View类表示的就是一个空白的矩形区域.常用的组件如TextView.Button.EditText等都直接或间接继承自View. 此外,View还有 ...

  8. android菜鸟学习笔记5----第一个android程序

    程序功能:点击一个按钮,然后弹出一个提示信息 Step 1:在eclipse中新建一个android application project,在创建过程中不勾选create activity,这样就创 ...

  9. android菜鸟学习笔记30----Android使用百度地图API(一)准备工作及在应用中显示地图

    1.准备工作: 百度地图API是免费开放的,但是需要申请API Key: 1)先注册一个百度开发者帐号 2)进入百度开放服务平台http://developer.baidu.com/ 3)进入LBS云 ...

随机推荐

  1. Destroy reall destroy ?!

    最近做战斗逻辑的时候发现一个问题 测试脚本mTest: public class mTest : MonoBehaviour { public mTest2 tmp2; void OnGUI() { ...

  2. HTML5中音频视频标签使用

    HTML5中音频视频标签使用的最好方式 Html5中提供了<audio> <vedio>元素实现音频视频的引入播放 然而更好的方式

  3. 【UVA】11468-Substring(AC自己主动机)

    AC自己主动机的题,须要注意的,建立失配边的时候,假设结点1失配边连到的那个结点2,那个结点2是一个单词的结尾,那么这个结点1也须要标记成1(由于能够看成,这个结点包括了这个单词),之后在Trie树上 ...

  4. iOS之基于FreeStreamer的简单音乐播放器(模仿QQ音乐)

    代码地址如下:http://www.demodashi.com/demo/11944.html 天道酬勤 前言 作为一名iOS开发者,每当使用APP的时候,总难免会情不自禁的去想想,这个怎么做的?该怎 ...

  5. asp.net+mvc+easyui+sqlite 简单用户系统学习之旅(六)—— 简单过滤器的使用

    有些同学喜欢在测试或运行项目时,直接跳转页面到Home/Index下,但本次项目直接输入Home/Index则会报错 因为home/index中有个user.name参数,如果启动项目后直接跳转到ho ...

  6. 自己写浏览器和webserver的分析!

    自己写浏览器和webserver 在android写一个浏览器 editText:输入网址ip:port/login.html.提交 把域名解析成ip 产生请求行 get login.html /r/ ...

  7. Hackerrank - Game Of Rotation 题解

    旋转一个数组以得到最大值. 陷阱就是:不能排序.须要模拟操作旋转,并设计公式计算旋转后的和. 要求是O(n)时间完毕. 原题: https://www.hackerrank.com/challenge ...

  8. Linux入门常用指令

    linux获取硬盘和目录大小的命令 df命令 Linux下可以用df命令获取硬盘的使用情况,通过man可以获取df命令的详细情况.df命令经常用的参数为: a:显示全部的档案系统和各分割区的磁盘使用情 ...

  9. mybatis学习笔记(14)-查询缓存之中的一个级缓存

    mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...

  10. poj2184 Cow Exhibition(p-01背包的灵活运用)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:id=2184">http://poj.org/problem?id=2184 Descrip ...