您的位置:首页 > 移动开发 > Android开发

android Json数据解析(一)

2016-10-10 22:11 316 查看

1.Json的相关简介

Json是独立于语言的,是一种轻量级文本交换格式,具有自我描述性,更容易理解。

2.Json的基础知识了解

1.Json的基本数据格式
①对象:格式:{“键”:各种类型的值}
②值:包括几种数据类型:String,int,数组,Object
2.如何解析json数据
1.先贴一段json数据:
{
"resultcode": "200",
"reason": "查询成功!",
"result": {
"sk": {	/*当前实况天气*/
"temp": "21",	/*当前温度*/
"wind_direction": "西风",	/*当前风向*/
"wind_strength": "2级",	/*当前风力*/
"humidity": "4%",	/*当前湿度*/
"time": "14:25"	/*更新时间*/
},
"today": {
"city": "天津",
"date_y": "2014年03月21日",
"week": "星期五",
"temperature": "8℃~20℃",	/*今日温度*/
"weather": "晴转霾",	/*今日天气*/
"weather_id": {	/*天气唯一标识*/
"fa": "00",	/*天气标识00:晴*/
"fb": "53"	/*天气标识53:霾 如果fa不等于fb,说明是组合天气*/
},
"wind": "西南风微风",
"dressing_index": "较冷", /*穿衣指数*/
"dressing_advice": "建议着大衣、呢外套加毛衣、卫衣等服装。",	/*穿衣建议*/
"uv_index": "中等",	/*紫外线强度*/
"comfort_index": "",/*舒适度指数*/
"wash_index": "较适宜",	/*洗车指数*/
"travel_index": "适宜",	/*旅游指数*/
"exercise_index": "较适宜",	/*晨练指数*/
"drying_index": ""/*干燥指数*/
},
"future": [	/*未来几天天气*/
{
"temperature": "28℃~36℃",
"weather": "晴转多云",
"weather_id": {
"fa": "00",
"fb": "01"
},
"wind": "南风3-4级",
"week": "星期一",
"date": "20140804"
},
{
"temperature": "28℃~36℃",
"weather": "晴转多云",
"weather_id": {
"fa": "00",
"fb": "01"
},
"wind": "东南风3-4级",
"week": "星期二",
"date": "20140805"
},
{
"temperature": "27℃~35℃",
"weather": "晴转多云",
"weather_id": {
"fa": "00",
"fb": "01"
},
"wind": "东南风3-4级",
"week": "星期三",
"date": "20140806"
},
{
"temperature": "27℃~34℃",
"weather": "多云",
"weather_id": {
"fa": "01",
"fb": "01"
},
"wind": "东南风3-4级",
"week": "星期四",
"date": "20140807"
},
{
"temperature": "27℃~33℃",
"weather": "多云",
"weather_id": {
"fa": "01",
"fb": "01"
},
"wind": "东北风4-5级",
"week": "星期五",
"date": "20140808"
},
{
"temperature": "26℃~33℃",
"weather": "多云",
"weather_id": {
"fa": "01",
"fb": "01"
},
"wind": "北风4-5级",
"week": "星期六",
"date": "20140809"
},
{
"temperature": "26℃~33℃",
"weather": "多云",
"weather_id": {
"fa": "01",
"fb": "01"
},
"wind": "北风4-5级",
"week": "星期日",
"date": "20140810"
}
]
},
"error_code": 0
}
2.解析步骤

①首先得到请求json数据的ip地址

String jsonStr = "您要请求的ip地址"
②然后把分析json数据,再进行解析
JSONObject jsonObject = new JSONObject(jsonStr);
int resultCode = jsonObject.getInt("resultcode");
if (resultCode == 200) {
JSONObject resultJsonArray = jsonObject.getJSONObject("result");
JSONObject resultJsonObject = resultJsonArray.getJSONObject("today");
String output = context.getString(R.string.city) + ": " + resultJsonObject.getString("city") + "\n"
+ context.getString(R.string.date_y) + ": " + resultJsonObject.getString("date_y") + "\n"
+ context.getString(R.string.week) + ": " + resultJsonObject.getString("week") + "\n"
+ context.getString(R.string.temperature) + ": " + resultJsonObject.getString("temperature") + "\n"
+ context.getString(R.string.weather) + ": " + resultJsonObject.getString("weather") + "\n"
+ context.getString(R.string.wind) + ": " + resultJsonObject.getString("wind") + "\n"
+ context.getString(R.string.dressing_index) + ": " + resultJsonObject.getString("dressing_index") + "\n"
+ context.getString(R.string.dressing_advice) + ": " + resultJsonObject.getString("dressing_advice") + "\n"
+ context.getString(R.string.uv_index) + ": " + resultJsonObject.getString("uv_index") + "\n"
+ context.getString(R.string.comfort_index) + ": " + resultJsonObject.getString("comfort_index") + "\n"
+ context.getString(R.string.wash_index) + ": " + resultJsonObject.getString("wash_index") + "\n"
+ context.getString(R.string.travel_index) + ": " + resultJsonObject.getString("travel_index") + "\n"
+ context.getString(R.string.exercise_index) + ": " + resultJsonObject.getString("exercise_index") + "\n";
tv_result.setText(output);
} else if (resultCode == 202) {
String reason = jsonObject.getString("reason");
tv_result.setText(reason);
} else {
Toast.makeText(context, "查询失败",
Toast.LENGTH_LONG).show();
tv_result.setText("");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

3.如何构建json数据

1.通过JSONObject直接创建

public void jsonObjectBuild(){
JSONObject zhangxing = new JSONObject();
Object objNull = null;
try {
zhangxing.put("name","zhangxing");//字符串
zhangxing.put("age",24);//int
zhangxing.put("sex","男");
zhangxing.put("habits",new String[]{"敲代码","写作","听歌"});//数组
zhangxing.put("isMarried",false);//boolean
zhangxing.put("car",objNull);//对象
KLog.i(zhangxing.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
2.通过Map构建

public void MapBuild(){
Map<String,Object> zhangxing = new HashMap<String,Object>();
Object objNull = null;
zhangxing.put("name","zhangxing");//字符串
zhangxing.put("age",24);//int
zhangxing.put("sex","男");
zhangxing.put("habits",new String[]{"敲代码","写作","听歌"});//数组
zhangxing.put("isMarried",false);//boolean
zhangxing.put("car",objNull);//对象
KLog.i(new JSONObject(zhangxing).toString());
}
3.通过JavaBean构建(在这里我利用Gson解析)

public void JavaBeanBuild(){
Gson gson = new Gson();
Zhangxing zhangxing = new Zhangxing();
zhangxing.setName("zhangxing");
zhangxing.setAge(24);
zhangxing.setSex("男");
zhangxing.setHabits(new String[]{"敲代码","写作","听歌"});
zhangxing.setCar(null);
zhangxing.setMarried(false);
KLog.e(gson.toJson(zhangxing));
}


数据效果图:



4.Json解析天气数据的症结

1.清单文件的配置(一定别忘了网络权限,我专门搞这种事哦,受不了)

<uses-permission android:name="android.permission.INTERNET"/>
2.准确分析json数据的结构,为后面的解析作铺垫。这里,如果json数据比较长且乱的话,我推荐一个格式化Json数据的工具HiJson,戳一戳下载吧

3.看清API的请求数据格式,我这里采用了聚合数据的天气API,聚合数据官网:https://www.juhe.cn/,注册之后创建自己的应用,然后代码里所需的key就诞生了。



这个是解析的重中之重,各种参数的非必须性都要搞清楚,有的能省略,有的是必须滴!!!!

4.最后就是导入org.apache.http的jar包了,下载地址:http://download.csdn.net/detail/u010213127/8490911





5.主要代码分析

1.lactivity_main 文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="城市:"
android:layout_marginLeft="60dp"
android:textSize="20sp" />

<EditText
android:id="@+id/city"
android:layout_width="wrap_content"
android:ems="8"
android:hint="请输入城市名"
android:layout_height="wrap_content"
android:inputType="text" />"
</LinearLayout>

<Button
android:id="@+id/query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"
android:layout_marginTop="30dp"
android:background="@color/colorAccent"
android:textSize="23sp" />

<TextView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2.MainActivity:

public class MainActivity extends Activity {
EditText et_city;
Button btn_query;
TextView tv_result;
QueryTask task;

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

et_city = (EditText)findViewById(R.id.city);
tv_result = (TextView)findViewById(R.id.result);
btn_query = (Button)findViewById(R.id.query);

btn_query.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String city = et_city.getText().toString();
if (city.length() < 1) {
Toast.makeText(MainActivity.this, "请输入城市名",
Toast.LENGTH_LONG).show();
return;
}
task = new QueryTask(MainActivity.this, tv_result);
task.execute(city);
}
});
}

}
在这里,MainActivity中出现了task.execute(city)这行代码,这里是调用AsyncTask的方法,后面再详细介绍QueryTask类,继承AysncTask.

3.QueryTask异步查询类:

public class QueryTask extends AsyncTask<String, Void, String> {
Context context;
TextView tv_result;

private static final String JUHE_URL_ENVIRONMENT_AIR_PM =
"http://v.juhe.cn/weather/index";
private static final String JUHE_APPKEY = "1ffb1f9476298c55fcf33051dc9c1f4c";

public QueryTask(Context context, TextView tv_result) {
// TODO Auto-generated constructor stub
super();
this.context = context;
this.tv_result = tv_result;
}

@Override
protected String doInBackground(String... params) {
String city = params[0];
String result = null;

ArrayList<NameValuePair> headerList = new ArrayList<NameValuePair>();
headerList.add(new BasicNameValuePair("Content-Type", "text/html; charset=utf-8"));

String targetUrl = JUHE_URL_ENVIRONMENT_AIR_PM;

ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
paramList.add(new BasicNameValuePair("cityname", city));
paramList.add(new BasicNameValuePair("dtype", "json"));
paramList.add(new BasicNameValuePair("key", JUHE_APPKEY));

for (int i = 0; i < paramList.size(); i++) {
NameValuePair nowPair = paramList.get(i);
String value = nowPair.getValue();
try {
value = URLEncoder.encode(value, "UTF-8");
} catch (Exception e) {
}
if (i == 0) {
targetUrl += ("?" + nowPair.getName() + "=" + value);
} else {
targetUrl += ("&" + nowPair.getName() + "=" + value);
}
}

HttpGet httpRequest = new HttpGet(targetUrl);
try {
for (int i = 0; i < headerList.size(); i++) {
httpRequest.addHeader(headerList.get(i).getName(),
headerList.get(i).getValue());
}

HttpClient httpClient = new DefaultHttpClient();

HttpResponse httpResponse = httpClient.execute(httpRequest);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(httpResponse.getEntity());
return result;
} else {
return result;
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}

@Override
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONObject jsonObject = new JSONObject(result);
int resultCode = jsonObject.getInt("resultcode");
if (resultCode == 200) {
JSONObject resultJsonArray = jsonObject.getJSONObject("result");
JSONObject resultJsonObject = resultJsonArray.getJSONObject("today");
String output = context.getString(R.string.city) + ": " + resultJsonObject.getString("city") + "\n"
+ context.getString(R.string.date_y) + ": " + resultJsonObject.getString("date_y") + "\n"
+ context.getString(R.string.week) + ": " + resultJsonObject.getString("week") + "\n"
+ context.getString(R.string.temperature) + ": " + resultJsonObject.getString("temperature") + "\n"
+ context.getString(R.string.weather) + ": " + resultJsonObject.getString("weather") + "\n"
+ context.getString(R.string.wind) + ": " + resultJsonObject.getString("wind") + "\n"
+ context.getString(R.string.dressing_index) + ": " + resultJsonObject.getString("dressing_index") + "\n"
+ context.getString(R.string.dressing_advice) + ": " + resultJsonObject.getString("dressing_advice") + "\n"
+ context.getString(R.string.uv_index) + ": " + resultJsonObject.getString("uv_index") + "\n"
+ context.getString(R.string.comfort_index) + ": " + resultJsonObject.getString("comfort_index") + "\n"
+ context.getString(R.string.wash_index) + ": " + resultJsonObject.getString("wash_index") + "\n"
+ context.getString(R.string.travel_index) + ": " + resultJsonObject.getString("travel_index") + "\n"
+ context.getString(R.string.exercise_index) + ": " + resultJsonObject.getString("exercise_index") + "\n";
tv_result.setText(output);
} else if (resultCode == 202) {
String reason = jsonObject.getString("reason");
tv_result.setText(reason);
} else {
Toast.makeText(context, "查询失败",
Toast.LENGTH_LONG).show();
tv_result.setText("");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}
MainActivity一旦执行了task.execute(city),那么他会主动的把city参数传给doInBackground()方法。主要代码:

<span style="color:#330000;">ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
paramList.add(new BasicNameValuePair("cityname", city));
paramList.add(new BasicNameValuePair("dtype", "json"));
paramList.add(new BasicNameValuePair("key", JUHE_APPKEY));</span>
这段代码多用于发送post请求时,把参数以键值对的形式保存在list中。其中的NameValuePair是一个得到返回参数值的接口,源码如下:

<span style="color:#330000;">package org.apache.http;

public interface NameValuePair {
String getName();

String getValue();
}</span>
BaseNameValuePair真正起了保存参数的作用,源码如下

<span style="color:#330000;">public BasicNameValuePair(String name, String value) {
if(name == null) {
throw new IllegalArgumentException("Name may not be null");
} else {
this.name = name;
this.value = value;
}
}</span>
最后遍历list,把参数都依次接入BaseUrl的后面,这里完整的请求ip就get了,哈哈,简单不?
<span style="color:#330000;"><span style="background-color: rgb(51, 0, 0);"></span></span>


<span style="color:#330000;">for (int i = 0; i < paramList.size(); i++) {
NameValuePair nowPair = paramList.get(i);
String value = nowPair.getValue();
try {
value = URLEncoder.encode(value, "UTF-8");
} catch (Exception e) {
}
if (i == 0) {
targetUrl += ("?" + nowPair.getName() + "=" + value);
} else {
targetUrl += ("&" + nowPair.getName() + "=" + value);
}
}</span> 
然后就是网络请求的代码了:

<span style="color:#330000;">HttpGet httpRequest = new HttpGet(targetUrl);
try {
for (int i = 0; i < headerList.size(); i++) {
httpRequest.addHeader(headerList.get(i).getName(),
headerList.get(i).getValue());
}

HttpClient httpClient = new DefaultHttpClient();

HttpResponse httpResponse = httpClient.execute(httpRequest);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(httpResponse.getEntity());
return result;
} else {
return result;
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}</span>

这里target已经是完整的ip了,所以用get请求喽,工程效果图:



源码下载吧,好了,又要跟大家说拜拜了,我是张星,欢迎关注。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息