Android(java)学习笔记151:Android中操作JSON数据(Json和Jsonarray)
1.Json 和 Xml
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。
[ XML ]
优点::
(1). 格式统一, 符合标准
(2). 容易与其他系统进行远程交互, 数据共享比较方便
缺点:
(1). XML文件格式文件庞大, 格式复杂, 传输占用带宽
(2). 服务器端和客户端都需要花费大量代码来解析XML, 不论服务器端和客户端代码变的异常复杂和不容易维护
(3). 客户端不同浏览器之间解析XML的方式不一致, 需要重复编写很多代码
(4). 服务器端和客户端解析XML花费资源和时间
[ JSON ]
优点:
(1). 数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小
(2). 易于解析这种语言, 客户端JavaScript可以简单的通过eval()进行JSON数据的读取
(3). 支持多种语言, 包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等语言服务器端语言, 便于服务器端的解析
(4). 在PHP世界, 已经有PHP-JSON和JSON-PHP出现了, 便于PHP序列化后的程序直接调用. PHP服务器端的对象、数组等能够直接生JSON格式, 便于客户端的访问提取.
(5). 因为JSON格式能够直接为服务器端代码使用, 大大简化了服务器端和客户端的代码开发量, 但是完成的任务不变, 且易于维护
缺点:
(1). 没有XML格式这么推广的深入人心和使用广泛, 没有XML那么通用性
(2). JSON格式目前在Web Service中推广还属于初级阶段
2.JSON语法
- 数据在键值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON 名称/值对
var json = '{"name":"imooc"}'; // 这个是正确的JSON格式 var json = "{\"name\":\"imooc\"}"; // 这个也是正确的JSON格式 var json = '{name:"imooc"}'; // 这个是错误的JSON格式,因为属性名没有用双引号包裹 var json = "{'name':'imooc'}";//这个也是错误的JSON格式,属性名用双引号包裹,而它用了单引号 // 检验JSON格式是否正确,可以使用 JSON.parse(json); 如果是正确的JSON格式,会返回一个对象
// 否则会报错 // 如果是对象的话,属性名可以不用双引号包裹 var obj = {name:"imooc"};
var obj = {"name":"imooc"};
var obj = {'name':'imooc'};
var obj = {"name":'imooc'};
var obj = {'name':"imooc"}; // 上述写法都是正确的。一般使用第一种形式最多,有些人可能为了保证跟JSON格式的字符串保持一致性,
// 也会使用第二种形式。。最后3种形式虽然是正确的,但不建议使用,容易挨打
JSON 表示数组
{
"people":[
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},
{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},
{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}
]
}
这不难理解。在这个示例中,只有一个名为 people的变量,值是包含三个条目的数组,每个条目是一个人的记录,其中包含名、姓和电子邮件地址。上面的示例演示如何用括号将记录组合成一个值。当然,可以使用相同的语法表示多个值(每个值包含多个记录):
{
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
}
jsonobject json对象。
{
mts:'1351234',
province:'重庆',
catName:'中国移动',
telString:'13512345678',
areaVid:'29404',
ispVid:'3236139',
carrier:'重庆移动'
}
3.下面结合一个案例,说明Android下如何通过网络访问解析Json数据:
(1)我们新建一个Android项目,如下:
(2)布局文件activity_main.xml:
<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="com.himi.json.MainActivity" > <EditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入电话号码"
android:inputType="phone"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"
android:onClick="click"
/> </LinearLayout>
布局效果图如下:
(3)我们获得网络端的Json数据是如下格式的:
我们要知道真正的JSON数据实体是:就是大括号包裹的部分就是JSON数据,这里就是没有"_GetZoneResult_= "(末尾含有一个空格)
{
mts:'1351234',
province:'重庆',
catName:'中国移动',
telString:'13512345678',
areaVid:'29404',
ispVid:'3236139',
carrier:'重庆移动'
}
回到MainActivity.java:
package com.himi.json; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL; import org.json.JSONObject; import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity {
private EditText et_phone; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_phone = (EditText) findViewById(R.id.et_phone); } public void click(View view) {
String phone = et_phone.getText().toString().trim();
final String path = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel="+phone; new Thread() {
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int code = conn.getResponseCode();
if (code == 200) {
// 得打JOSN数据,字符串
InputStream is = conn.getInputStream();
String json = StreamTools.readStream(is).replace("_GetZoneResult_= ", "");
//System.out.println(json);
JSONObject jsonObject = new JSONObject();
final String catName = jsonObject.getString("catName");
final String province = jsonObject.getString("province");
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "运营商: "+catName+"\n归属地: "+province,
0).show();
};
});
} else {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "资源没有找到或者是服务器出了问题",0).show();
};
}); }
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "访问网络失败",0).show();
};
}); }
};
}.start();
} }
Toast土司是更新UI操作,它是不能出现在子线程new Thread()之中的,之前说过这里可以使用handler消息机制通知主线程进行UI更新,这里有了更加方便的API就是runOnUiThread()方法,这个方法的源码如下:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
这个方法将Runnable接口内部执行的内容在主线程执行;
这里源码可以看出它是先判断当前线程是否是UI主线程,不是的话就利用handler发送消息给主线程进行相应操作,如果当前线程是主线程,就直接在当前线程中执行。
还有这里利用我们之前自己编写的一个API,将流转化为字符串的工具类StreamTools:
package com.himi.json; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream; /**
* 流的工具类
*
* @author Administrator
*
*/
public class StreamTools {
/**
* 把输入流的内容转换成字符串
*
* @param is
* @return null解析失败, string读取成功
*/
public static String readStream(InputStream is) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
String temptext = new String(baos.toByteArray());
return new String(baos.toByteArray(), "gbk");
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
(4)其实上面出现了很多的runOnUiThread(),我们可以抽取一个方法包裹这部分代码:
代码优化如下:
package com.himi.json; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL; import org.json.JSONObject; import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity {
private EditText et_phone; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_phone = (EditText) findViewById(R.id.et_phone); } public void click(View view) {
String phone = et_phone.getText().toString().trim();
final String path = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel="+phone; new Thread() {
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int code = conn.getResponseCode();
if (code == 200) {
// 得打JOSN数据,字符串
InputStream is = conn.getInputStream();
String json = StreamTools.readStream(is).replace("__GetZoneResult_= ", "");
//System.out.println(json);
JSONObject jsonObject = new JSONObject(json);
final String catName = jsonObject.getString("catName");
final String province = jsonObject.getString("province");
showToastInAnyThread("运营商: "+catName+"\n归属地: "+province);
} else {
showToastInAnyThread("资源没有找到或者是服务器出了问题"); }
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
showToastInAnyThread("访问失败"); }
};
}.start();
} public void showToastInAnyThread(final String text) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,text,0).show();
};
});
} }
最后工程的一览图:
(5)布署程序到模拟器上运行效果如下图:
4. Jsonarray的使用
(1)新建一个Android工程"11_jsonArray",如下:
(2)首先我们设置一下UI界面,如下:
<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="com.himi.jsonarray.MainActivity" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" > <TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:layout_weight="1"
android:text="姓名:"
android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView
android:id="@+id/tv_name"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:layout_weight="3" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" > <TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:layout_weight="1"
android:text="年龄:"
android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView
android:id="@+id/tv_age"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:layout_weight="3" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" > <TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:layout_weight="1"
android:text="国籍:"
android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView
android:id="@+id/tv_country"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:layout_weight="3" />
</LinearLayout> </LinearLayout>
布局效果如下:
(3)MainActivity,如下:
package com.himi.jsonarray; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView; public class MainActivity extends Activity {
private TextView tv_name;
private TextView tv_age;
private TextView tv_country; private String jsonStr = "{carrier:'重庆移动'}";
private String jsonArrStr = "[{name:'刘德华',age:'54',country:'中国'},"
+ "{name:'梁朝伟',age:'53',country:'中国'},"
+ "{name:'成龙',age:'61',country:'中国'}]";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_name = (TextView) findViewById(R.id.tv_name);
tv_age = (TextView) findViewById(R.id.tv_age);
tv_country = (TextView) findViewById(R.id.tv_country);
try {
JSONArray jsonArray = new JSONArray(jsonArrStr);
for (int i = 0; i < 3; i++) {
System.out.println(jsonArray.get(i).toString());
}
JSONObject jsonObject = new JSONObject(jsonArray.get(0).toString());
String name = jsonObject.getString("name");
String age = jsonObject.getString("age");
String country = jsonObject.getString("country"); tv_name.setText(name);
tv_name.setTextSize(25);
tv_age.setText(age);
tv_age.setTextSize(25);
tv_country.setText(country);
tv_country.setTextSize(25);
} catch (JSONException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} } }
(4)布署程序到模拟器上,如下:
Android(java)学习笔记151:Android中操作JSON数据(Json和Jsonarray)的更多相关文章
- Android:日常学习笔记(10)———使用LitePal操作数据库
Android:日常学习笔记(10)———使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式 ...
- Java学习笔记:基本输入、输出数据操作实例分析
Java学习笔记:基本输入.输出数据操作.分享给大家供大家参考,具体如下: 相关内容: 输出数据: print println printf 输入数据: Scanner 输出数据: JAVA中在屏幕中 ...
- Android开发学习笔记-关于Android的消息推送以及前后台切换
下面是最简单的Android的消息推送的实现方法 package com.example.shownotic; import java.util.Random; import android.supp ...
- 10.3(Java学习笔记)JDBC时间操作
一.时间分类 数据库 java类 Date ---- java.sql.Date 表示日期 yyyy-MM--dd (年月日) Time ----java.sql.Time 表示 ...
- Java学习笔记——可视化Swing中JTable控件绑定SQL数据源的两种方法
在 MyEclipse 的可视化 Swing 中,有 JTable 控件. JTable 用来显示和编辑常规二维单元表. 那么,如何将 数据库SQL中的数据绑定至JTable中呢? 在这里,提供两种方 ...
- Java学习笔记七(目录操作)
1.介绍 上一篇博客介绍的是java中经常使用的操作文件的方式,本篇博客着重解说一下,在Java中是怎样来操作目录的.主要是利用的是Java.IO包以下的File类,本篇博客着重解说一下该类的构造函数 ...
- Java学习笔记40(sql:将数据库内数据存入对象中)
新建一个数据表: use qy97; create table student( id int primary key auto_increment, sname ), gander ), age i ...
- Java学习笔记之[ 利用扫描仪Scanner进行数据输入 ]
/*********数据的输入********//**利用扫描仪Scanner进行数据输入 怎么使用扫描仪Scanner *1.放在类声明之前,引入扫描仪 import java.util.Scann ...
- Android 数字签名学习笔记
Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
随机推荐
- Linux 静态库 & 动态库
转自:http://blog.chinaunix.net/uid-26833883-id-3219335.html 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...
- 运行程序时抛出异常“找不到请求的 .Net Framework Data Provider。可能没有安装。”
方法1 如果系统未安装Oracle Data Provider 请参考方法2 右键单击项目,选择属性,切换到“生成”选项卡,将目标平台改为 Any CPU,并勾选“首选32位” 方法2 安装 Orac ...
- C++构造函数和拷贝构造函数详解
构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险. 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含 ...
- CodeForces 723F【DFS瞎搞】
题意: 给你一幅图,你要用这些边构造一个树, s和t两个节点的度数不能超过ds dt 而且图是保证没有环 思路: 树的性质是:无环(已经保证),无向(保证),连通(还要判断) 首先把S,T点从图里剥离 ...
- java日期时间处理集合
本文主要介绍java中日期时间的处理,包括获取时间,时间相加减,格式化等操作. 持续更新中... 时间格式化 //时间格式化 SimpleDateFormat dateFormat = new Sim ...
- bzoj 2007: [Noi2010]海拔【最小割+dijskstra】
上来就跑3e5的最大流--脑子抽了 很容易看出,每个地方的海拔都是0或1因为再高了没有意义,又,上去下来再上去没有意义,所以最后一定是从s连着一片0,剩下连着t一片1,然后有贡献的就是01交接的那些边 ...
- LeetCode.897-递增搜索树(Increasing Order Search Tree)
这是悦乐书的第346次更新,第370篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第211题(顺位题号是897).给定一棵树,按中序遍历顺序重新排列树,以便树中最左边的节 ...
- (十四)SpringBoot开发微信授权支付
前提:配置好域名,在公众号配置 一.引用jar包,在pom.xml文件加入依赖 <dependency> <groupId>com.github.binarywang</ ...
- 01 | Jewels and Stones
Question You're given strings J representing the types of stones that are jewels, and S representing ...
- mySql分组排序
mysql 排序学习---mysql 1.建表语句 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varc ...