Android json解析使用总结(二)
在前一篇《android json解析使用总结(一)》中介绍了一些关于json的基础知识,这一篇主要通过一个例子来实际演示一下android中如何解析从服务器或其他地方返回的json格式的数据。本次主要实现的是天气预报例子,里面主要涉及到“百度车联网API的使用”、“android Json解析”、等知识点,通过这个简单的demo,我们便可以熟悉如何解析json格式的数据。
首先,我们从“百度车联网API官网”中获取key,这是我们能否使用百度提供的服务的关键,具体的步骤不详述。通过这个API我们可以从浏览器端查看获取天气json格式的数据,如下所示:
天气URL:
- http://api.map.baidu.com/telematics/v3/weather?location=常州&output=json&ak=ECIqazfmQFiEj0HAZKupo44x
- {
- "error": 0,
- "status": "success",
- "date": "2015-08-06",
- "results": [
- {
- "currentCity": "常州",
- "pm25": "68",
- "index": [
- {
- "title": "穿衣",
- "zs": "炎热",
- "tipt": "穿衣指数",
- "des": "天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。"
- },
- {
- "title": "洗车",
- "zs": "较适宜",
- "tipt": "洗车指数",
- "des": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
- },
- {
- "title": "旅游",
- "zs": "一般",
- "tipt": "旅游指数",
- "des": "天气较好,温度高,让人感觉热,幸好风比较大,能缓解炎热的天气。外出旅游请注意防暑降温和防晒。"
- },
- {
- "title": "感冒",
- "zs": "少发",
- "tipt": "感冒指数",
- "des": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。"
- },
- {
- "title": "运动",
- "zs": "较适宜",
- "tipt": "运动指数",
- "des": "天气较好,但因气温较高且风力较强,请适当降低运动强度并注意户外防风。"
- },
- {
- "title": "紫外线强度",
- "zs": "中等",
- "tipt": "紫外线强度指数",
- "des": "属中等强度紫外线辐射天气,外出时建议涂擦SPF高于15、PA+的防晒护肤品,戴帽子、太阳镜。"
- }
- ],
- "weather_data": [
- {
- "date": "周四 08月06日 (实时:31℃)",
- "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
- "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
- "weather": "多云",
- "wind": "东南风3-4级",
- "temperature": "36 ~ 27℃"
- },
- {
- "date": "周五",
- "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
- "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
- "weather": "多云转阵雨",
- "wind": "东南风3-4级",
- "temperature": "35 ~ 27℃"
- },
- {
- "date": "周六",
- "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/zhenyu.png",
- "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
- "weather": "阵雨",
- "wind": "东风4-5级",
- "temperature": "32 ~ 26℃"
- },
- {
- "date": "周日",
- "dayPictureUrl": "http://api.map.baidu.com/images/weather/day/zhenyu.png",
- "nightPictureUrl": "http://api.map.baidu.com/images/weather/night/zhenyu.png",
- "weather": "阵雨",
- "wind": "东南风4-5级",
- "temperature": "31 ~ 26℃"
- }
- ]
- }
- ]
- }
通过以上对json格式的数据分析,我们可以知道:这里面既包含简单的JSONObject对象如“status、date”等节点,又包含复杂的JSONArray对象如“results、index、weather_data”节点,属于一个混合模型的json格式数据,这就需要我们一步一步来解析。
第一步,在本地新建一个WeatherBean用来存放解析到的天气数据,里面主要有“日期、风向、气温...”等字段
- package com.lj.weather.model;
- public class WeatherInfo {
- private String dateWeek="";
- private String nightPictureUrl="";
- private String dayPictureUrl = "http://api.map.baidu.com/images/weather/day/duoyun.png";
- private String weather = "多云转晴";
- private String wind = "北风3-4级";
- private String temperature = "22 ~ 12℃";
- public WeatherInfo() {
- };
- public void setDateWeek(String dateWeek){
- this.dateWeek=dateWeek;
- }
- public String getDateWeek(){
- return dateWeek;
- }
- public void setdayPictureUrl(String dayPictureUrl){
- this.dayPictureUrl=dayPictureUrl;
- }
- public String getdayPictureUrl(){
- return dayPictureUrl;
- }
- public void setnightPictureUrl(String nightPictureUrl){
- this.nightPictureUrl=nightPictureUrl;
- }
- public String getnightPictureUrl(){
- return nightPictureUrl;
- }
- public void setweather(String weather){
- this.weather=weather;
- }
- public String getweather(){
- return weather;
- }
- public void setwind(String wind){
- this.wind=wind;
- }
- public String getwind(){
- return wind;
- }
- public void settemperature(String temperature){
- this.temperature=temperature;
- }
- public String gettemperature(){
- return temperature;
- }
- }
第二步,写一个工具类,用于网络请求根据url获取json格式的天气数据并将其转化为字符串输出,
- package com.lj.weather.utils;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- public class JSONUtils {
- public JSONUtils (){};
- /**
- * 通过url 向服务器发送请求,服务器返回json数据
- * @param url
- * url地址
- * @return
- * string类型的json格式数据
- */
- public String getJSON(String url){
- StringBuilder builder=new StringBuilder();
- HttpGet httpRequest=new HttpGet(url);
- try {
- HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(),
- "UTF-8"));
- for (String s = reader.readLine(); s != null; s = reader.readLine()) {
- builder.append(s);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return builder.toString();
- }
- }
第三步,我们便开始具体的解析上面获取到的json格式的字符串天气数据。代码里我都有详细的注释,所以就不多加解释了。
- package com.lj.weather.act;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.http.impl.conn.tsccm.WaitingThread;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import com.lj.weather.R;
- import com.lj.weather.adapter.NextWeatherAdapter;
- import com.lj.weather.model.WeatherDetailInfo;
- import com.lj.weather.model.WeatherInfo;
- import com.lj.weather.utils.JSONUtils;
- import android.R.string;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.Toast;
- /**
- * 简单的天气预报显示界面
- *
- * @author Administrator
- *
- */
- public class WeatherInfoShowAct extends Activity {
- private String text = "";
- private TextView item_date;
- private TextView item_wind;
- private TextView item_temperature;
- private TextView item_weather;
- private JSONUtils jsonUtils;
- private WeatherInfo weatherInfo, weatherInfo1;
- private List<WeatherInfo> weatherInfoList;
- private String uri = "http://api.map.baidu.com/telematics/v3/weather?location=常州&output=json&ak=ECIqazfmQFiEj0HAZKupo44x";
- private ListView listView;
- private NextWeatherAdapter adapter;
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (msg.what == 1) {
- //服务器返回的天气jsonText文本
- String infoString = (String) msg.obj;
- //天气数据list,今天,明天、后天、大后天
- weatherInfoList = getWeatherInfo(infoString);
- Log.d("Main", "" + weatherInfoList.size());
- adapter = new NextWeatherAdapter(weatherInfoList, WeatherInfoShowAct.this);
- listView.setAdapter(adapter);
- item_date.setText(weatherInfo1.getDateWeek());
- item_wind.setText(weatherInfo1.getwind());
- item_temperature.setText(weatherInfo1.gettemperature());
- item_weather.setText(weatherInfo1.getweather());
- }
- };
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_weather_main);
- initView();
- }
- private void initView() {
- jsonUtils = new JSONUtils();
- listView = (ListView) findViewById(R.id.head_list);
- new Thread() {
- public void run() {
- //根据url获得jsontext的天气数据
- text = jsonUtils.getJSON(uri);
- //刷新UI
- Message message = new Message();
- message.what = 1;
- message.obj = text;
- mHandler.sendMessage(message);
- };
- }.start();
- item_date = (TextView) findViewById(R.id.head_date);
- item_temperature = (TextView) findViewById(R.id.head_temperature);
- item_weather = (TextView) findViewById(R.id.head_weather);
- item_wind = (TextView) findViewById(R.id.head_wind);
- }
- private List<WeatherInfo> getWeatherInfo(String jsonStr) {
- try {
- JSONObject jsonObjectFirst = new JSONObject(jsonStr);
- /** error */
- if (jsonObjectFirst.get("error").equals(0)) {
- Log.d("error", "" + jsonObjectFirst.get("error"));
- Log.d("status", "" + jsonObjectFirst.get("status"));
- Log.d("date", "" + jsonObjectFirst.get("date"));
- /** results */
- JSONArray jsonArrayResults = (JSONArray) jsonObjectFirst.get("results");
- /** weather_data */
- //为什么要get(0)?因为它属于第一个数组里面,其实总共只有一个数组
- JSONObject jsonObjectWeatherData = (JSONObject) jsonArrayResults.get(0);
- //获取当前城市
- Log.d("currentCity", jsonObjectWeatherData.getString("currentCity"));
- //获取当前城市的PM值
- Log.d("pm25", jsonObjectWeatherData.getString("pm25"));
- JSONArray jsonArrayWeatherData = (JSONArray) jsonObjectWeatherData.get("weather_data");
- weatherInfoList = new ArrayList<WeatherInfo>();
- for (int i = 0; i < 4; i++) {
- JSONObject jsonObjectFour = (JSONObject) jsonArrayWeatherData.get(i);
- //明天、后天、大后天数据
- if (i >= 1) {
- weatherInfo = new WeatherInfo();
- weatherInfo.setDateWeek("" + jsonObjectFour.get("date"));
- weatherInfo.setdayPictureUrl("" + jsonObjectFour.get("dayPictureUrl"));
- weatherInfo.setnightPictureUrl("" + jsonObjectFour.get("nightPictureUrl"));
- weatherInfo.setweather("" + jsonObjectFour.get("weather"));
- weatherInfo.setwind("" + jsonObjectFour.get("wind"));
- weatherInfo.settemperature("" + jsonObjectFour.get("temperature"));
- weatherInfoList.add(weatherInfo);
- } else {
- //今天数据
- weatherInfo1 = new WeatherInfo();
- weatherInfo1.setDateWeek("" + jsonObjectFour.get("date"));
- weatherInfo1.setdayPictureUrl("" + jsonObjectFour.get("dayPictureUrl"));
- weatherInfo1.setnightPictureUrl("" + jsonObjectFour.get("nightPictureUrl"));
- weatherInfo1.setweather("" + jsonObjectFour.get("weather"));
- weatherInfo1.setwind("" + jsonObjectFour.get("wind"));
- weatherInfo1.settemperature("" + jsonObjectFour.get("temperature"));
- }
- }
- Log.d("size", "" + weatherInfoList.size());
- } else {
- Toast.makeText(WeatherInfoShowAct.this, "天气数据解析出错", 1).show();
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return weatherInfoList;
- }
- }
最后,我们运行一下查看最后的效果:
以上便是解析的全部过程,在这个demo中主要涉及到了网络请求、线程的使用、百度车联网服务的使用以及json数据的解析,在这个demo基础上,我们可以稍微修改一下,譬如增加刷新按钮、增加城市选择等便可以做出一个天气APP来,最后附上源码。