android中json数据分析及解析详解
来源:互联网 发布:mac gnu getopt 编辑:程序博客网 时间:2024/05/29 08:43
1.写在前面
通过郭神的代码和说明加上这两天查看的资料,学到了很多以前没注意没总结的json知识。通过这篇文章可以了解到以下几点。
A. json数据形式,一般有三种
jsonObject:{key:value},只要是这种形式的json数据,一定要写成key-value。并且如果是这样的数据,不管多复杂,如下图(郭神的数据),如果使用JSONObect解析,第一步一定是将字符串数据变成JSONObject,如下
JSONObject jsonObject = new JSONObject(获取到的string数据);
JSONArray:[],这里可以分为两种,[{},{},{}]和[“”,”“,111,true],不管哪一种这数组中一个要至少有一个数据,并且如果要使用JSONArray解析,不管多复杂的数据结构,见下图(郭神的数据),第一步都是使用下面这行代码,
JSONArray jsonArray = new JSONArray(string类型的数据);
这是他们的共同点。不同点,是[{},{}]这种类型的JSONArray,{}对象里面一定是JSONObject,即一定要写成key-value形式。
B. 学习到了GSON解析和JSONObject或者JSONArray解析的区别,GSON解析如果要获取整个json数据中某一个字段的数据,(下面有例子),一般通过把bean写好,然后通过方法,直接可以获取字段外面的对象,然后通过对象通过get或者.属性获取数据。但是JSONObject或者JSONArray需要一层层剥洋葱样剥到某个字段的数值,并且要获取最外层对象,还要一层层从里面的对象塞数据,知道塞到我们想要的。
C. 对于一个json数据,我们想要什么字段的数据就在bean里面写好自己想要数据的字段,一定要写准确,如果担心字段的名字不符合我们java定义属性的名字,可以通过GSON库里面SerializedName解决,还是一样,一定要写匹配。如下图,整个json数据中,我只是想要获取,这两个字段的value也是可以的。(下面例子)
"lat":"28.197000","lon":"112.967000"
D. 发现一个查看json数据的好工具HiJson 2.1.2_jdk64.exe,可以通过它将复杂的json数据格式化。当然此类的工具很多,在线的也很多,如果,见图。
2. 代码
A. 首先上面我说了很多非常确定的言语,现在验证下。
比较这两个,明显可以知道上面这个不是json数据,放到工具验证,见图{"a":"bbb","b":2,"c":true,"d"}{"a":"bbb","b":2,"c":true,"d":22.22}
还有这种
["a",true,22.2,333,{"aa"}]和["a",true,22.2,333,{"aa":"ccc"}]
上面说了,只要是{}里面的一定要是key-value形式,不然一定不是json数据,所以前面的不是json数据,后面的才是,顺便说一句,前面也说了,只要是这种[]形式,如果要用JSONArray解析,通过下标value。
B. 写了个小例子,主要是为了学习,JSONObject和JSONArray解析json数据。数据来源就是上面说的两个
这里写链接内容
这里写链接内容
开始说了,对于第一个数据,我要全部解析出来,并且把省份的名字显示成一个列表。对于第二个数据,我要获取其中两个字段的value。见效果图。
布局代码就不贴了,很简单,两个button和一个listview。并且我这里请求接口用的是okhttp3。
首先去工具看清楚这个json数据。
根据上面的这是[{},{},{}]的数据,更巧的是这{}里面的字段key是一样的,所以可以直接看成一个对象,而这整个是个这个对象的数组。所以我把这个对象写出来为Province,代码如下,这没什么好说的,字段匹配即可。
package guo.com.jsondataparse;import com.google.gson.annotations.SerializedName;/** * Created by ${GuoZhaoHui} on 2017/3/9. * email:guozhaohui628@gmail.com */public class Province { @SerializedName("id") public int id; @SerializedName("name") public String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
假设我们已经网络请求,获取到这个json字符串了,先写一个方法解析这个数据。前面也说了,只要是[]这种类型的都是先放到JSONArray中,
JSONArray jsonArray = new JSONArray(response);
这样就变成了一个json数组了,每个数组的元素都是JSONObject,所以我可以对这个数组循环遍历,
for(int i=0;i<jsonArray.length();i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); Province province = new Province(); province.setId(jsonObject.getInt("id")); province.setName(jsonObject.getString("name")); provinceList.add(province); }
只要一个JSONObject接近到字段,都是可以通过JOSNObject.getString(“”)或者其他方法拿到value。我这里选择把循环拿到的value保存到list中。
代码如下:
/** * 从json数据解析成对象 * @param response * @return */ public List<Province> parseJsonProvince(String response){ try { JSONArray jsonArray = new JSONArray(response); List<Province> provinceList = new ArrayList<>(); for(int i=0;i<jsonArray.length();i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); Province province = new Province(); province.setId(jsonObject.getInt("id")); province.setName(jsonObject.getString("name")); provinceList.add(province); } return provinceList; } catch (JSONException e) { e.printStackTrace(); } return null; }
接下来的代码大致就是点击按钮,开启线程用okhttp3请求,获取response,用刚才的方法解析成list,对着个list循环遍历,获取list中对象的name属性,保存成为一个list。切换到主线程,用listview加载适配器。代码如下
this.findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(){ @Override public void run() { super.run(); sendOkHttpRequest(URL1, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { provinceList = parseJsonProvince(response.body().string()); for(Province province:provinceList){ stringList.add(province.getName()); } runOnUiThread(new Runnable() { @Override public void run() { ArrayAdapter arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, stringList); listView.setAdapter(arrayAdapter); } }); } }); } }.start(); } });
现在对第二个数据解析,我需要获取到这个数据中的lat和lon两个字段的value,见图
思路:因为是这种形式的{},所以第一步一定是
JSONObject jsonObject = new JSONObject(response);
然后可以看到这个key对应的value是个[],所以通过key拿到value,key一定要写对,最好复制
JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");
然后再看结构,我们需要的两个value在basic这个字段中,而basic是这个数组中的第一个元素对象中的一个字段,所以如果我们把basic堪称一个对象,则这两个字段就是其中的属性。所以先把basic这个对象定义出来
package guo.com.jsondataparse;import com.google.gson.annotations.SerializedName;/** * Created by ${GuoZhaoHui} on 2017/3/10. * email:guozhaohui628@gmail.com */public class Basic { @SerializedName("lat") public String lat; @SerializedName("lon") public String log; public String getLat() { return lat; } public void setLat(String lat) { this.lat = lat; } public String getLog() { return log; } public void setLog(String log) { this.log = log; } @Override public String toString() { return "Basic{" + "lat='" + lat + '\'' + ", log='" + log + '\'' + '}'; }}
json数据中basic中包含很多字段,但是我们不需要,所以写上两个我们需要的属性。然后我把数组[]中的第一个元素堪称对象weather,所以weather的类就是这样子
package guo.com.jsondataparse;import com.google.gson.annotations.SerializedName;/** * Created by ${GuoZhaoHui} on 2017/3/10. * email:guozhaohui628@gmail.com */public class Weather { @SerializedName("basic") public Basic basic;}
同理,我这里只是定义其中我们需要的属性。
拿到这个[]中的第一个元素,看json我们知道是个{},所以是JSONObject
JSONObject jsonWeather = jsonArray.getJSONObject(0);
对于这个JSONObject其实是这养的{“basic”:{“lat”:”28.222”,”lon”:”112.22”}},所以同理我们通过key获取到这个value,这个value也是个JSONObject。
JSONObject jsonBasic = jsonWeather.getJSONObject("basic");
到了这一步,这个JSONObject已经接近我们需要的字段了,所以直接通过拿到value。
jsonBasic.getString("lat")jsonBasic.getString("lon")
代码如下:
/** * 解析天气json数据中的lat和log两个字段,并将解析出来的数据存到Basic对象中 * @param response * @return */ public Basic parseJsonBasic(String response){ try { Basic basic = new Basic(); JSONObject jsonObject = new JSONObject(response); JSONArray jsonArray = jsonObject.getJSONArray("HeWeather"); //GSON解析方法// String jsonWeather = jsonArray.getJSONObject(0).toString();// Weather weather = new Gson().fromJson(jsonWeather,Weather.class);// basic = weather.basic; JSONObject jsonWeather = jsonArray.getJSONObject(0); JSONObject jsonBasic = jsonWeather.getJSONObject("basic"); basic.setLat(jsonBasic.getString("lat")); basic.setLog(jsonBasic.getString("lon")); Log.i(TAG, basic.toString()); return basic; } catch (JSONException e) { e.printStackTrace(); } return null; }
接下来的思路和第一个按钮点击一样,首先点击按钮,在里面开启线程获取json数据,通过刚才的方法解析数据,切换到主线程,弹出一个吐司框
this.findViewById(R.id.bt2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(){ @Override public void run() { super.run(); sendOkHttpRequest(URL2, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { final Basic basic = parseJsonBasic(response.body().string()); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this,"经纬度-->"+basic.toString(),Toast.LENGTH_SHORT).show(); } }); } }); } }.start(); } });
3. 源码地址
源码
- android中json数据分析及解析详解
- android中json数据解析详解
- android JSON数据解析分析
- 【Android】解析JSON数据详解
- Android中JSON数据解析
- Android中解析Json数据
- Android中解析Json数据
- Android--Json数据及Xml数据解析
- JSON数据构造及解析详解
- Android中JSON格式及JSON解析
- Android——JSON数据解析详解
- android解析json数据的详解实例
- android 数据解析 JSON 开发详解+视频
- Android json数据解析及简单例子
- json解析数据详解
- Json数据解析详解
- Android中Gson解析详解json
- Android中使用Gson解析JSON数据
- Nodejs图片验证码,支持window和mac,svg验证码
- IDEA使用--字体、编码和基本设置
- [Java]内部类
- LeetCode----Maximum Subarray (E) / Maximum Product Subarray (M)
- CSS:position
- android中json数据分析及解析详解
- AJAX工作原理及其优缺点
- Launcher sample code
- ubuntu 更新数据源
- 凡事只要做到极致,终会开花结果
- AutoCompleteTextView 简单用法
- 接口和监听器
- 华为oj初级 百钱买白鸡
- Appuploader-让你在Windows下上传iOS APP到苹果应用商店