你的位置:首页 > 操作系统

[操作系统]android菜鸟学习笔记25


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

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

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

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

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

 1 <?php 2  3 if(isset($_REQUEST["username"])&& isset($_REQUEST["password"])){ 4  5    $username = $_REQUEST["username"]; 6  7    $password = $_REQUEST["password"]; 8  9    if($username == "zhangsan" && $password == "123"){10 11      $arr = array(12 13            "errorCode"=>200,14 15            "errorMsg"=>"login success"16 17       );18 19      echo json_encode($arr);20 21    }else{22 23      $arr = array(24 25            "errorCode"=>404,26 27            "errorMsg"=>"login failure"28 29       );30 31      echo json_encode($arr);32 33    }34 35 }else{36 37    $arr = array(38 39            "errorCode"=>500,40 41            "errorMsg"=>"illeagle params"42 43       );44 45    echo json_encode($arr);46 47 }48 49 ?>

返回的信息格式如下:

{"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数据的解析:

 1 private Handler handler = new Handler(){ 2  3      public void handleMessage(android.os.Message msg) { 4  5         if(msg.what == OK){ 6  7            String str = msg.obj.toString(); 8  9            try {10 11               JSONObject obj = new JSONObject(str);12 13               Log.i(TAG,obj.getString("errorCode"));14 15               Log.i(TAG,obj.getString("errorMsg"));16 17            } catch (JSONException e) {18 19               // TODO Auto-generated catch block20 21               e.printStackTrace();22 23            }24 25           26 27          }28 29       }30 31 };

运行结果:

 

 

有时候,服务端返回的可能是一些实体类信息,若用户登录成功,返回存放用户个人信息用以缓存在本地,这时,可能希望直接能将返回的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:

 1 package cn.csc.start.bean; 2  3  4  5 public class ResponseInfo { 6  7    private int errorCode; 8  9    private String errorMsg;10 11    public int getErrorCode() {12 13      return errorCode;14 15    }16 17    public void setErrorCode(int errorCode) {18 19      this.errorCode = errorCode;20 21    }22 23    public String getErrorMsg() {24 25      return errorMsg;26 27    }28 29    public void setErrorMsg(String errorMsg) {30 31      this.errorMsg = errorMsg;32 33    }34 35    public ResponseInfo(int errorCode, String errorMsg) {36 37      super();38 39      this.errorCode = errorCode;40 41      this.errorMsg = errorMsg;42 43    }44 45    public ResponseInfo() {46 47      super();48 49    }50 51 }

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

1 Gson gson = new Gson();2 3 ResponseInfo info = gson.fromJson(str, ResponseInfo.class);4 5 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"}]解析的具体代码如下:

1 Gson gson = new Gson();2 3 TypeToken<List<ResponseInfo>> list = new TypeToken<List<ResponseInfo>>(){};4 5 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请求

 1 private void async_get_test(){ 2  3      String username = et_username.getText().toString(); 4  5      String password = et_password.getText().toString(); 6  7      AsyncHttpClient client = new AsyncHttpClient(); 8  9      client.get("http://10.0.2.2/index.php?username="+username+"&password="+password, new AsyncHttpResponseHandler() {10 11         12 13          @Override14 15         public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {16 17            // TODO Auto-generated method stub18 19            Message msg = new Message();20 21            msg.what = OK;22 23            msg.obj = new String(responseBody);24 25            handler.sendMessage(msg);26 27          }28 29         30 31          @Override32 33         public void onFailure(int statusCode, Header[] headers,34 35               byte[] responseBody, Throwable error) {36 37            // TODO Auto-generated method stub38 39            Message msg = new Message();40 41            msg.what = OK;42 43            msg.obj = new String(responseBody);44 45            handler.sendMessage(msg);46 47          }48 49       });50 51    }

使用AsyncHttpClient发送post请求

     

 1 private void async_post_test(){ 2  3      String username = et_username.getText().toString(); 4  5      String password = et_password.getText().toString(); 6  7      AsyncHttpClient client = new AsyncHttpClient(); 8  9      RequestParams params = new RequestParams();10 11      params.add("username", username);12 13      params.add("password", password);14 15      client.post("http://10.0.2.2/index.php", params , new AsyncHttpResponseHandler() {16 17         18 19          @Override20 21         public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {22 23            // TODO Auto-generated method stub24 25            Message msg = new Message();26 27            msg.what = OK;28 29            msg.obj = new String(responseBody);30 31            handler.sendMessage(msg);32 33          }34 35         36 37          @Override38 39         public void onFailure(int statusCode, Header[] headers,40 41               byte[] responseBody, Throwable error) {42 43            // TODO Auto-generated method stub44 45            Message msg = new Message();46 47            msg.what = OK;48 49            msg.obj = new String(responseBody);50 51            handler.sendMessage(msg);52 53          }54 55       });56 57 }

 

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

get方式:

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

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

post方式:

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

RequestParams params = new RequestParams();

params.add("username", username);

params.add("password", password);

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

 




福建旅游住宿攻略福建旅游最佳时间福建自驾游最佳路线福建旅游多少钱福建旅游报价价格坐着地铁三号线 游南京必去的八个美景 2015清明节东莞去哪赏花?东莞清明节踏青赏花去哪里? 2015清明节梦幻百花洲门票多少钱?东莞梦幻百花洲清明节要门票吗? 东莞梦幻百花洲4月开什么花?4月去梦幻百花洲看什么花? 隐贤山庄门票多少钱?东莞常平隐贤山庄最佳旅游时间? 2015东莞隐贤山庄樱花节介绍?隐贤山庄樱花节活动? 情人节坐着游艇看湖景温泉 2015隐贤山庄樱花节时间?2015东莞隐贤山庄樱花节什么时候? 南海影视城位置?佛山南海影视城详细地址? 秋季无锡哪里赏花好? 哪些人是不适合泡温泉的? 多山多川多浪漫 自由私奔去山川乡(组图) 澳门一日游能游览澳门全部景点吗?路线怎么安排? 香港有哪些种类的手表?怎样买到货真价实的手表? 在香港迪士尼乐园中吃饭贵吗?有哪些餐厅? 香港哪里有书店?香港哪里有书买? AQ12EA5R1DAJME Datasheet AQ12EA5R1DAJME Datasheet SQCA5C103MATME Datasheet SQCA5C103MATME Datasheet 08055G334ZAT2A Datasheet 08055G334ZAT2A Datasheet 牡丹江参团去港澳 牡丹江参团去港澳 牡丹江参团去港澳 长春参团去港澳 长春参团去港澳 长春参团去港澳 佳木斯出发去香港旅游 佳木斯出发去香港旅游 佳木斯出发去香港旅游