博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示...
阅读量:5950 次
发布时间:2019-06-19

本文共 17799 字,大约阅读时间需要 59 分钟。

Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示


今天项目中要实现一个天气的预览,加载的信息很多,字段也很多,所以理清了一下思路,准备独立出来写一个总结,这样对大家还是很有帮助的,老司机要开车了

涉及到网络,你就一定要先添加权限,准没错

一.归属地查询(JSONObject)

这个也是最简单的一类Json了,我的博客

里面不管是手机归属地查询还是QQ吉凶,解析得到的Json都是最简单的类型,我们这里以手机归属地为例来讲述

这里的接口

http://apis.juhe.cn/mobile/get?phone=18679606764&key=22a6ba14995ce26dd0002216be51dabb

这里说明一下,我们现在以及接下来的例子,都会用到Volley来解析接口得到Json,所以不会用Volley的话可以先去看一下上面的两篇文章

Volley你到哪都能下载到,就不详细说了

既然我们接口有了,我们就开始解析吧

/**     * 解析接口     */    private void Volley_Get() {        String url = "http://apis.juhe.cn/mobile/get?phone=" + myPhone                + "&key=22a6ba14995ce26dd0002216be51dabb";        RequestQueue queue = Volley.newRequestQueue(this);        StringRequest request = new StringRequest(Method.PUBLIC, url,                new Response.Listener
() { // 成功 @Override public void onResponse(String json) { Log.i("Json", json); } }, new Response.ErrorListener() { // 失败 @Override public void onErrorResponse(VolleyError errorLog) { Log.e("Error", errorLog.toString()); } }); queue.add(request); }

这样,我们就解析得到了一串JSON,也就是今天本文中的主角

{    "error_code": 0,    "reason": "Return Successd!",    "result": {        "areacode": "0796",        "card": "江西联通GSM卡",        "city": "吉安",        "company": "中国联通",        "province": "江西",        "zip": "343000"    },    "resultcode": "200"}

我们可以看到,JSON是由一个大括号括起来的,里面是键值对,每一个键对应一个值,当然,他里面还有一个result的大括号包裹着一堆数据,这里我推荐一个工具叫

  • HiJson(网上有下,自行搜索一下就可以了)

我们来看他的构造

这里写图片描述

这里看起来就十分的清晰了,我们一层层的剥下来,这里要用到的就是我们org.json下的JSONObject类

/**     * 解析Json     *     * @param json     */    private void Volley_Json(String json) {        try {            JSONObject jsonObject = new JSONObject(json);            JSONObject object = jsonObject.getJSONObject("result");            tv_content.setText("归属地:" + object.getString("province") + "-"                    + object.getString("city") + "\n" + "区号:" + object.getString("areacode")                    + "\n" + "运营商:" + object.getString("company")                    + "\n" + "用户类型:" + object.getString("card"));        } catch (JSONException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

这里,我们可以看到,我们new一个JSONObject 并且把json穿进去解析,然后getJSONObject获取一个json里面的字段,再去用getString(name)去获取键得到值,所以运行结果

这里写图片描述

是不是没什么难度?那我们来稍微做一个难一点的,笑话大全

二.笑话大全(JSONArray)

我们同样的,需要一个接口

http://japi.juhe.cn/joke/content/list.from?key=56e5f85c150ebd54461ae4fb7c6705ec&page=1&pagesize=1&sort=asc&time=1418745237

然后我们继续用Volley来解析这个接口得到Json

/**     * 解析接口     */    private void Volley_Get() {        String url = "http://japi.juhe.cn/joke/content/list.from?key=56e5f85c150ebd54461ae4fb7c6705ec&page=1&pagesize=1&sort=asc&time=1418745237";        RequestQueue queue = Volley.newRequestQueue(this);        StringRequest request = new StringRequest(Method.PUBLIC, url,                new Response.Listener
() { // 成功 @Override public void onResponse(String json) { Log.i("Json", json); } }, new Response.ErrorListener() { // 失败 @Override public void onErrorResponse(VolleyError errorLog) { Log.e("Error", errorLog.toString()); } }); queue.add(request); }

这样,我们得到的JSON就是

{    "error_code": 0,    "reason": "Success",    "result": {        "data": [            {                "content": "大脑:别睡了快起来吧要迟到了。 身体:滚,别烦我我还要再躺会。 时间:你俩慢慢吵我先溜了。 尿:再不起我就出来了!",                "hashId": "0ee18f8733dc6744e6db6d0312839e5b",                "unixtime": 1462885431,                "updatetime": "2016-05-10 21:03:51"            }        ]    }}

我们需要的是中间的文字,但是这个json和之前那个json就有点不一样了,这个明显里面有一个数组,所以我们要用JSONArray数组来解析了,我们先来看一下结构

这里写图片描述

这个结构明显要复杂一些,就在Data里面他里面还有一个数组,所以我们解析起来就要先遍历一下了

/**     * 解析Json     *     * @param json     */    private void Volley_Json(String json) {        try {            JSONObject jsonObject = new JSONObject(json);            JSONObject jsonObject2 = jsonObject.getJSONObject("result");            JSONArray ja = jsonObject2.getJSONArray("data");            for (int i = 0; i < ja.length(); i++) {                JSONObject jsonObject3 = (JSONObject) ja.get(i);                tv_content.setText(jsonObject3.getString("content"));            }        } catch (JSONException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

我们可以看到,我们是一层一层的去解析的,首先是解析得到最外面的result,返回的是一个JSONObject ,然后继续解析data,返回的是一个JSONArray,然后我们遍历一下 JSONObject jsonObject3 = (JSONObject) ja.get(i);强转成一个JSONObject ,解析到最后我们就可以直接getString(“content”)拿到数据了,是不是思路很清晰?我们看一下效果图

这里写图片描述

三.天气预报(JSONArray * 2)

这个也是比较复杂的,也是我项目中有用到的,就是一个JSON里面有数组,数组里面也有数组,这样嵌套,其实说难也不难,只要掌握了思路,剩下的,只不过就是工作量的问题了

这里我们用到的接口是和风天气的接口

  • 官网:

接口

https://api.heweather.com/x3/weather?city=%E6%B7%B1%E5%9C%B3&key=你的key

我们先用Volley解析接口

/**     * 获取天气     *     * @param city 城市名     */    private void getWeather(String city) {        String url = "https://api.heweather.com/x3/weather?city=" + city                + "&key=你的key";        RequestQueue queue = Volley.newRequestQueue(this);        StringRequest request = new StringRequest(Request.Method.GET, url,                new Response.Listener
() { // 成功 @Override public void onResponse(String json) { Log.i("json", json); } }, new Response.ErrorListener() { // 失败 @Override public void onErrorResponse(VolleyError errorLog) { Log.e("Error", errorLog.toString()); } }); queue.add(request); }

这里,我们解析到了Json,有点长哦

{    "HeWeather data service 3.0": [        {            "aqi": {                "city": {                    "aqi": "60",                    "co": "1",                    "no2": "53",                    "o3": "46",                    "pm10": "65",                    "pm25": "42",                    "qlty": "良",                    "so2": "7"                }            },            "basic": {                "city": "深圳",                "cnty": "中国",                "id": "CN101280601",                "lat": "22.544000",                "lon": "114.109000",                "update": {                    "loc": "2016-05-10 22:07",                    "utc": "2016-05-10 14:07"                }            },            "daily_forecast": [                {                    "astro": {                        "sr": "05:45",                        "ss": "18:54"                    },                    "cond": {                        "code_d": "301",                        "code_n": "101",                        "txt_d": "强阵雨",                        "txt_n": "多云"                    },                    "date": "2016-05-10",                    "hum": "70",                    "pcpn": "25.4",                    "pop": "98",                    "pres": "1008",                    "tmp": {                        "max": "32",                        "min": "23"                    },                    "vis": "7",                    "wind": {                        "deg": "216",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "4"                    }                },                {                    "astro": {                        "sr": "05:44",                        "ss": "18:54"                    },                    "cond": {                        "code_d": "101",                        "code_n": "300",                        "txt_d": "多云",                        "txt_n": "阵雨"                    },                    "date": "2016-05-11",                    "hum": "64",                    "pcpn": "0.0",                    "pop": "13",                    "pres": "1008",                    "tmp": {                        "max": "29",                        "min": "23"                    },                    "vis": "10",                    "wind": {                        "deg": "118",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "10"                    }                },                {                    "astro": {                        "sr": "05:44",                        "ss": "18:55"                    },                    "cond": {                        "code_d": "300",                        "code_n": "101",                        "txt_d": "阵雨",                        "txt_n": "多云"                    },                    "date": "2016-05-12",                    "hum": "68",                    "pcpn": "0.1",                    "pop": "7",                    "pres": "1009",                    "tmp": {                        "max": "29",                        "min": "25"                    },                    "vis": "10",                    "wind": {                        "deg": "129",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "7"                    }                },                {                    "astro": {                        "sr": "05:44",                        "ss": "18:55"                    },                    "cond": {                        "code_d": "101",                        "code_n": "302",                        "txt_d": "多云",                        "txt_n": "雷阵雨"                    },                    "date": "2016-05-13",                    "hum": "69",                    "pcpn": "9.8",                    "pop": "53",                    "pres": "1011",                    "tmp": {                        "max": "29",                        "min": "23"                    },                    "vis": "7",                    "wind": {                        "deg": "123",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "1"                    }                },                {                    "astro": {                        "sr": "05:43",                        "ss": "18:56"                    },                    "cond": {                        "code_d": "302",                        "code_n": "302",                        "txt_d": "雷阵雨",                        "txt_n": "雷阵雨"                    },                    "date": "2016-05-14",                    "hum": "73",                    "pcpn": "5.3",                    "pop": "66",                    "pres": "1011",                    "tmp": {                        "max": "29",                        "min": "23"                    },                    "vis": "10",                    "wind": {                        "deg": "115",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "10"                    }                },                {                    "astro": {                        "sr": "05:43",                        "ss": "18:56"                    },                    "cond": {                        "code_d": "302",                        "code_n": "302",                        "txt_d": "雷阵雨",                        "txt_n": "雷阵雨"                    },                    "date": "2016-05-15",                    "hum": "69",                    "pcpn": "7.7",                    "pop": "58",                    "pres": "1009",                    "tmp": {                        "max": "29",                        "min": "22"                    },                    "vis": "10",                    "wind": {                        "deg": "166",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "4"                    }                },                {                    "astro": {                        "sr": "05:42",                        "ss": "18:57"                    },                    "cond": {                        "code_d": "302",                        "code_n": "101",                        "txt_d": "雷阵雨",                        "txt_n": "多云"                    },                    "date": "2016-05-16",                    "hum": "67",                    "pcpn": "1.8",                    "pop": "50",                    "pres": "1008",                    "tmp": {                        "max": "28",                        "min": "23"                    },                    "vis": "10",                    "wind": {                        "deg": "10",                        "dir": "无持续风向",                        "sc": "微风",                        "spd": "8"                    }                }            ],            "hourly_forecast": [                {                    "date": "2016-05-10 22:00",                    "hum": "89",                    "pop": "38",                    "pres": "1009",                    "tmp": "27",                    "wind": {                        "deg": "80",                        "dir": "东风",                        "sc": "微风",                        "spd": "4"                    }                }            ],            "now": {                "cond": {                    "code": "101",                    "txt": "多云"                },                "fl": "28",                "hum": "88",                "pcpn": "0",                "pres": "1008",                "tmp": "25",                "vis": "10",                "wind": {                    "deg": "10",                    "dir": "南风",                    "sc": "3-4",                    "spd": "14"                }            },            "status": "ok",            "suggestion": {                "comf": {                    "brf": "较不舒适",                    "txt": "白天天气多云,同时会感到有些热,不很舒适。"                },                "cw": {                    "brf": "不宜",                    "txt": "不宜洗车,路面积水较多,不宜擦洗汽车。如果执意擦洗,要做好溅上泥水的心理准备。"                },                "drsg": {                    "brf": "热",                    "txt": "天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"                },                "flu": {                    "brf": "少发",                    "txt": "各项气象条件适宜,无明显降温过程,发生感冒机率较低。"                },                "sport": {                    "brf": "较适宜",                    "txt": "天气较好,户外运动请注意防晒,推荐您在室内进行低强度运动。"                },                "trav": {                    "brf": "适宜",                    "txt": "天气较好,但丝毫不会影响您出行的心情。温度适宜又有微风相伴,适宜旅游。"                },                "uv": {                    "brf": "弱",                    "txt": "紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"                }            }        }    ]}

这里,我们可以根据结构图来分析

这里写图片描述

这里我们可以看到,他本身就是一个数组,接着又是一个数组,数组里面包含着接下来七天的天气情况,这里呢,我们就不做的特别详细了,我们写三天 ,怎么写呢?看着哈

/**     * 解析Json     *     * @param json     */    private void Volley_Json(String json) {        try {            JSONObject jsonObject = new JSONObject(json);            JSONArray jArray = jsonObject                    .getJSONArray("HeWeather data service 3.0");            for (int i = 0; i < jArray.length(); i++) {
JSONObject jb1 = (JSONObject) jArray.get(i); JSONArray jr1 = jb1.getJSONArray("daily_forecast"); for (int j = 0; j < jr1.length(); j++) {
JSONObject jb2 = (JSONObject) jr1.get(j); JSONObject jb3 = jb2.getJSONObject("tmp"); dateList.add(jb2.getString("date")); weatherList.add(jb2.getJSONObject("cond") .getString("txt_n")); TmpList.add(jb3.getString("min") + "-" + jb3.getString("max")); } } // 设置参数 today_date.setText(dateList.get(0)); today_weather.setText(weatherList.get(0)); today_tmp.setText(TmpList.get(0)); tomorrow_date.setText(dateList.get(1)); tomorrow_weather.setText(weatherList.get(1)); tomorrow_tmp.setText(TmpList.get(1)); after_date.setText(dateList.get(2)); after_weather.setText(weatherList.get(2)); after_tmp.setText(TmpList.get(2)); //设置图片 if (weatherList.get(0).equals("晴")) { today_img.setImageResource(R.mipmap.sun); } else if (weatherList.get(0).equals("多云")) { today_img.setImageResource(R.mipmap.cloudy); } else { today_img.setImageResource(R.mipmap.rain); } if (weatherList.get(1).equals("晴")) { tomorrow_img.setImageResource(R.mipmap.sun); } else if (weatherList.get(1).equals("多云")) { tomorrow_img.setImageResource(R.mipmap.cloudy); } else { tomorrow_img.setImageResource(R.mipmap.rain); } if (weatherList.get(2).equals("晴")) { arter_img.setImageResource(R.mipmap.sun); } else if (weatherList.get(2).equals("多云")) { arter_img.setImageResource(R.mipmap.cloudy); } else { arter_img.setImageResource(R.mipmap.rain); } } catch (JSONException e) { e.printStackTrace(); } //清空数据 dateList.clear(); weatherList.clear(); TmpList.clear(); }

这里代码虽然多,但是后半部分基本上可以不看,就是设置数据和图片的,我们这里同样的getJSONArray获取到整个数组,然后开始遍历这个数组,强转为JSONObject 之后我们再次的获取每天的小数组daily_forecast,到这里,就和上面一样了,我们又强转为JSONObject 就可以开始getString(name)了,但是我们这里要获取三天的数据,所以我用一个List装起来,然后拿出来设置到TextView上,然后再根据天气设置图片,最后,清空一下List,因为他每次请求我们都是只获取他的前三天数据,所以运行的结果就是这样:

这里写图片描述

是不是这篇博客挺实用的,如果觉得好的话,可以点个赞哟,谢谢大家了

Demo下载:

我的群,通往Android的神奇之旅 :555974449,欢迎大家进来交流技术!

你可能感兴趣的文章
温故js系列(11)-BOM
查看>>
Vuex学习
查看>>
bootstrap - navbar
查看>>
切图崽的自我修养-[ES6] 编程风格规范
查看>>
[React Native Android 安利系列]样式与布局的书写
查看>>
利用dxflib读写cad文件
查看>>
《DOM编程艺术》中CSS—DOM的总结(一)
查看>>
服务器迁移小记
查看>>
FastDFS存储服务器部署
查看>>
Android — 创建和修改 Fragment 的方法及相关注意事项
查看>>
(cons '(贰 . 输入/输出) 《为自己写本-Guile-书》)
查看>>
this全面解析(二)
查看>>
流程控制: jQ Deferred 与 ES6 Promise 使用新手向入坑!
查看>>
从零开始写个编译器吧 - tao 语言的文法定义(下)
查看>>
使用 .NET 平台,如何玩转 Universal Windows 应用?
查看>>
Android 如何自定义EditText 下划线?
查看>>
17 行代码实现的简易 Javascript 字符串模板
查看>>
[LintCode] Identical Binary Tree
查看>>
从零开始写个编译器吧 - 程序流控制
查看>>
在 GitHub 上创建一个 Swift 包:其实一点也不简单
查看>>