Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示
Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示
今天项目中要实现一个天气的预览,加载的信息很多,字段也很多,所以理清了一下思路,准备独立出来写一个总结,这样对大家还是很有帮助的,老司机要开车了
涉及到网络,你就一定要先添加权限,准没错
<!--网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
一.归属地查询(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<String>() {
// 成功
@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<String>() {
// 成功
@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<String>() {
// 成功
@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下载:http://download.csdn.net/detail/qq_26787115/9516126
我的群,通往Android的神奇之旅 :555974449,欢迎大家进来交流技术!
Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示的更多相关文章
- Asp.net Json数据解析的一种思路
在日常的编码中,经常会遇到JSON类型的数据,有简单的,也有复杂的.对于简单的,我们可以用正则等匹配,但是一旦遇到复杂的,就比较难办了. 数据分析 目前手头上需要制作一个天气预报功能,现成的接口已经有 ...
- Android JSON数据解析(数据传输)
上篇随笔详细介绍了三种解析服务器端传过来的xml数据格式,而对于服务器端来说,返回给客户端的数据格式一般分为html.xml和json这三 种格式,那么本篇随笔将讲解一下json这个知识点,包括如何通 ...
- Android json 数据解析
1.json格式 2.json解析 3.gson解析 4.fastjson解析 一.Json格式 json一种轻量级的数据交换格式.在网络上传输交换数据一般用xml, json. 两种结构: 1)对象 ...
- Android JSON数据解析(GSON方式)
要创建和解析JSON数据,也可以使用GSON来完成.GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库.使用GSON,可以很容易的将一串JSON数据转换为一个Jav ...
- json原生解析
身为新手,在运用网络解析json数据的时候,发现先会用Gson等框架解析json,然后就懒起来学原生解析了,这下在看别人写的demo的时候就尴尬了,一块块的,不懂写什么,气氛十分尴尬. 不多说,先来条 ...
- [转]JSon数据解析的四种方式
转至http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的js ...
- android JSON数据格式 解析
一. JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧. Json建构于两种结构: 最后再加一种格式在文章的最后显示出来非常少有的格式 ...
- Android Json数据解析
1.通过主Activity的Button按钮进行解析 public class MainActivity extends Activity { private Button button=null; ...
- IOS - JSON数据解析 小3种方法
[manager GET:serverURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject ...
随机推荐
- JavaScript 流程语句知识脑图
- python3.6 使用 pymysql 连接 Mysql 数据库及 简单的增删改查操作
1.通过 pip 安装 pymysql 进入 cmd 输入 pip install pymysql 回车等待安装完成: 安装完成后出现如图相关信息,表示安装成功. 2.测试连接 import ...
- Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
原文地址:http://www.javatang.com JVM Heap Dump(堆转储文件)的生成 正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了J ...
- Programming In Scala笔记-第十九章、类型参数,协变逆变,上界下界
本章主要讲Scala中的类型参数化.本章主要分成三个部分,第一部分实现一个函数式队列的数据结构,第二部分实现该结构的内部细节,最后一个部分解释其中的关键知识点.接下来的实例中将该函数式队列命名为Que ...
- Redis源码剖析--源码结构解析
请持续关注我的个人博客:https://zcheng.ren 找工作那会儿,看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识.在面试过程中,redis确实 ...
- Android自动打包工具aapt详解
概念 在Android.mk中有LOCAL_AAPT_FLAGS配置项,在gradle中也有aaptOptions,那么aapt到底是干什么的呢? aapt即Android Asset Packagi ...
- 如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列投到队列尾的元素个数(包含队列头、队列尾)。
#include <iostream> using namespace std; //循环队列(少用一个空间)长度 #define M (8+1) typedef struct node ...
- Chrome 内存和CPU消耗量双料冠军
今天统计了下某个时刻各进程的内存和CPU使用概况.结果发现,Chrome消耗量真是不一般的大.比Windows主进程都还猛! 另外发现百度安全卫士占用CPU也比较猛. powershell下输入: p ...
- hbase高性能读取数据
有时需要从hbase中一次读取大量的数据,同时对实时性有较高的要求.可以从两方面进行考虑:1.hbase提供的get方法提供了批量获取数据方法,通过组装一个list<Get> gets即可 ...
- Android动态加载入坑指南
曾几何时,国内各大公司掀起了一股研究Android动态加载的技术,两年多过去了,动态加载技术俨然成了Android开发中必须掌握的技术.那么动态加载技术是什么呢,这里谈谈我的个人看法,如有雷同,纯属偶 ...