android java json_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 语法是 JavaScript 对象表示语法的子集。

数据在键值对中

数据由逗号分隔

花括号保存对象

方括号保存数组

JSON 名称/值对

JSON 数据的书写格式是:名称/值对。

名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开:

"firstName":"John"

这很容易理解,等价于这条 JavaScript 语句:

firstName="John"

一个对象以"{"开始,以"}"结束。 每个"名称"后跟一个":"  ,"键/值"对"之间使用","分隔

但是,当将多个"名称 / 值对"串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个"名称 / 值对"的 记录,比如:

{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"}

1 var json = '{"name":"imooc"}'; //这个是正确的JSON格式

2

3 var json = "{\"name\":\"imooc\"}"; //这个也是正确的JSON格式

4

5 var json = '{name:"imooc"}'; //这个是错误的JSON格式,因为属性名没有用双引号包裹

6

7 var json = "{'name':'imooc'}";//这个也是错误的JSON格式,属性名用双引号包裹,而它用了单引号

8

9 //检验JSON格式是否正确,可以使用 JSON.parse(json); 如果是正确的JSON格式,会返回一个对象

10 //否则会报错

11

12 //如果是对象的话,属性名可以不用双引号包裹

13

14 var obj = {name:"imooc"};15 var obj = {"name":"imooc"};16 var obj = {'name':'imooc'};17 var obj = {"name":'imooc'};18 var obj = {'name':"imooc"};19

20 //上述写法都是正确的。一般使用第一种形式最多,有些人可能为了保证跟JSON格式的字符串保持一致性,

21 //也会使用第二种形式。。最后3种形式虽然是正确的,但不建议使用,容易挨打

JSON表示数组

当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名列表。在XML中,需要许多开始标记和结束标记;如果使用典型的名称 / 值对(就像在本系列前面文章中看到的那种名称 / 值对),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstName这样的形式。

如果使用 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项目,如下:

6c798cd76c19c23b76a5e095a5332db0.png

(2)布局文件activity_main.xml:

1

2 xmlns:tools="http://schemas.android.com/tools"

3 android:layout_width="match_parent"

4 android:layout_height="match_parent"

5 android:orientation="vertical"

6 tools:context="com.himi.json.MainActivity" >

7

8

10 android:layout_width="match_parent"

11 android:layout_height="wrap_content"

12 android:hint="请输入电话号码"

13 android:inputType="phone"/>

14

16 android:layout_height="wrap_content"

17 android:text="查询"

18 android:onClick="click"

19 />

20

21

布局效果图如下:

5f9ea39b023ed63219cd15b97e068938.png

(3)我们获得网络端的Json数据是如下格式的:

62b46c1c7a399a90cc6d0587c8a428f1.png

我们要知道真正的JSON数据实体是:就是大括号包裹的部分就是JSON数据,这里就是没有"_GetZoneResult_= "(末尾含有一个空格)

{

mts:'1351234',

province:'重庆',

catName:'中国移动',

telString:'13512345678',

areaVid:'29404',

ispVid:'3236139',

carrier:'重庆移动'

}

回到MainActivity.java:

1 packagecom.himi.json;2

3 importjava.io.IOException;4 importjava.io.InputStream;5 importjava.net.HttpURLConnection;6 importjava.net.MalformedURLException;7 importjava.net.ProtocolException;8 importjava.net.URL;9

10 importorg.json.JSONObject;11

12 importandroid.app.Activity;13 importandroid.os.Bundle;14 importandroid.view.View;15 importandroid.widget.EditText;16 importandroid.widget.Toast;17

18 public class MainActivity extendsActivity {19 privateEditText et_phone;20

21 @Override22 protected voidonCreate(Bundle savedInstanceState) {23 super.onCreate(savedInstanceState);24 setContentView(R.layout.activity_main);25 et_phone =(EditText) findViewById(R.id.et_phone);26

27

28

29 }30

31 public voidclick(View view) {32 String phone =et_phone.getText().toString().trim();33 final String path = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel="+phone;34

35 newThread() {36 public voidrun() {37 try{38 URL url = newURL(path);39 HttpURLConnection conn =(HttpURLConnection) url.openConnection();40 conn.setRequestMethod("GET");41 conn.setConnectTimeout(5000);42 conn.setReadTimeout(5000);43 int code =conn.getResponseCode();44 if (code == 200) {45 //得打JOSN数据,字符串

46 InputStream is =conn.getInputStream();47 String json = StreamTools.readStream(is).replace("_GetZoneResult_= ", "");48 //System.out.println(json);

49 JSONObject jsonObject = newJSONObject();50 final String catName = jsonObject.getString("catName");51 final String province = jsonObject.getString("province");52 runOnUiThread(newRunnable() {53 public voidrun() {54 Toast.makeText(MainActivity.this, "运营商: "+catName+"\n归属地: "+province,55 0).show();56 };57 });58 } else{59 runOnUiThread(newRunnable() {60 public voidrun() {61 Toast.makeText(MainActivity.this, "资源没有找到或者是服务器出了问题",0).show();62 };63 });64

65 }66 } catch(Exception e) {67 //TODO 自动生成的 catch 块

68 e.printStackTrace();69 runOnUiThread(newRunnable() {70 public voidrun() {71 Toast.makeText(MainActivity.this, "访问网络失败",0).show();72 };73 });74

75 }76 };77 }.start();78 }79

80

81 }

Toast土司是更新UI操作,它是不能出现在子线程new Thread()之中的,之前说过这里可以使用handler消息机制通知主线程进行UI更新,这里有了更加方便的API就是runOnUiThread()方法,这个方法的源码如下:

1 public final voidrunOnUiThread(Runnable action) {2 if (Thread.currentThread() !=mUiThread) {3 mHandler.post(action);4 } else{5 action.run();6 }7 }

这个方法将Runnable接口内部执行的内容在主线程执行;

这里源码可以看出它是先判断当前线程是否是UI主线程,不是的话就利用handler发送消息给主线程进行相应操作,如果当前线程是主线程,就直接在当前线程中执行。

还有这里利用我们之前自己编写的一个API,将流转化为字符串的工具类StreamTools:

1 packagecom.himi.json;2

3 importjava.io.ByteArrayOutputStream;4 importjava.io.IOException;5 importjava.io.InputStream;6

7 /**

8 * 流的工具类9 *10 *@authorAdministrator11 *12 */

13 public classStreamTools {14 /**

15 * 把输入流的内容转换成字符串16 *17 *@paramis18 *@returnnull解析失败, string读取成功19 */

20 public staticString readStream(InputStream is) {21 try{22 ByteArrayOutputStream baos = newByteArrayOutputStream();23 byte[] buffer = new byte[1024];24 int len = -1;25 while ((len = is.read(buffer)) != -1) {26 baos.write(buffer, 0, len);27 }28 is.close();29 String temptext = newString(baos.toByteArray());30 return new String(baos.toByteArray(), "gbk");31 } catch(IOException e) {32 e.printStackTrace();33 return null;34 }35 }36 }

(4)其实上面出现了很多的runOnUiThread(),我们可以抽取一个方法包裹这部分代码:

代码优化如下:

1 packagecom.himi.json;2

3 importjava.io.IOException;4 importjava.io.InputStream;5 importjava.net.HttpURLConnection;6 importjava.net.MalformedURLException;7 importjava.net.ProtocolException;8 importjava.net.URL;9

10 importorg.json.JSONObject;11

12 importandroid.app.Activity;13 importandroid.os.Bundle;14 importandroid.view.View;15 importandroid.widget.EditText;16 importandroid.widget.Toast;17

18 public class MainActivity extendsActivity {19 privateEditText et_phone;20

21 @Override22 protected voidonCreate(Bundle savedInstanceState) {23 super.onCreate(savedInstanceState);24 setContentView(R.layout.activity_main);25 et_phone =(EditText) findViewById(R.id.et_phone);26

27

28

29 }30

31 public voidclick(View view) {32 String phone =et_phone.getText().toString().trim();33 final String path = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel="+phone;34

35 newThread() {36 public voidrun() {37 try{38 URL url = newURL(path);39 HttpURLConnection conn =(HttpURLConnection) url.openConnection();40 conn.setRequestMethod("GET");41 conn.setConnectTimeout(5000);42 conn.setReadTimeout(5000);43 int code =conn.getResponseCode();44 if (code == 200) {45 //得打JOSN数据,字符串

46 InputStream is =conn.getInputStream();47 String json = StreamTools.readStream(is).replace("__GetZoneResult_= ", "");48 //System.out.println(json);

49 JSONObject jsonObject = newJSONObject(json);50 final String catName = jsonObject.getString("catName");51 final String province = jsonObject.getString("province");52 showToastInAnyThread("运营商: "+catName+"\n归属地: "+province);53 } else{54 showToastInAnyThread("资源没有找到或者是服务器出了问题");55

56 }57 } catch(Exception e) {58 //TODO 自动生成的 catch 块

59 e.printStackTrace();60 showToastInAnyThread("访问失败");61

62 }63 };64 }.start();65 }66

67 public void showToastInAnyThread(finalString text) {68 runOnUiThread(newRunnable() {69 public voidrun() {70 Toast.makeText(MainActivity.this,text,0).show();71 };72 });73 }74

75

76 }

最后工程的一览图:

7dc44d0b2d65da5a5047e71bf5d59d31.png

(5)布署程序到模拟器上运行效果如下图:

e40f9e310eae6546759e14bc5b043919.png

4.Jsonarray的使用

(1)新建一个Android工程"11_jsonArray",如下:

aaf5f1660e8e457ddaf3979e65494849.png

(2)首先我们设置一下UI界面,如下:

1

2 xmlns:tools="http://schemas.android.com/tools"

3 android:layout_width="match_parent"

4 android:layout_height="match_parent"

5 android:orientation="vertical"

6 tools:context="com.himi.jsonarray.MainActivity" >

7

8

10 android:layout_height="wrap_content"

11 android:orientation="horizontal" >

12

13

15 android:layout_height="wrap_content"

16 android:layout_marginLeft="5dip"

17 android:layout_marginTop="5dip"

18 android:layout_weight="1"

19 android:text="姓名:"

20 android:textAppearance="?android:attr/textAppearanceLarge"/>

21

22

24 android:layout_width="0dip"

25 android:layout_height="wrap_content"

26 android:layout_marginTop="5dip"

27 android:layout_weight="3" />

28

29

30

32 android:layout_height="wrap_content"

33 android:orientation="horizontal" >

34

35

37 android:layout_height="wrap_content"

38 android:layout_marginLeft="5dip"

39 android:layout_marginTop="5dip"

40 android:layout_weight="1"

41 android:text="年龄:"

42 android:textAppearance="?android:attr/textAppearanceLarge"/>

43

44

46 android:layout_width="0dip"

47 android:layout_height="wrap_content"

48 android:layout_marginTop="5dip"

49 android:layout_weight="3" />

50

51

52

54 android:layout_height="wrap_content"

55 android:orientation="horizontal" >

56

57

59 android:layout_height="wrap_content"

60 android:layout_marginLeft="5dip"

61 android:layout_marginTop="5dip"

62 android:layout_weight="1"

63 android:text="国籍:"

64 android:textAppearance="?android:attr/textAppearanceLarge"/>

65

66

68 android:layout_width="0dip"

69 android:layout_height="wrap_content"

70 android:layout_marginTop="5dip"

71 android:layout_weight="3" />

72

73

74

布局效果如下:

8d4d00e91d907c1d94c1096437e34319.png

(3)MainActivity,如下:

1 packagecom.himi.jsonarray;2

3 importorg.json.JSONArray;4 importorg.json.JSONException;5 importorg.json.JSONObject;6

7 importandroid.app.Activity;8 importandroid.os.Bundle;9 importandroid.widget.TextView;10

11 public class MainActivity extendsActivity {12 privateTextView tv_name;13 privateTextView tv_age;14 privateTextView tv_country;15

16 private String jsonStr = "{carrier:'重庆移动'}";17 private String jsonArrStr = "[{name:'刘德华',age:'54',country:'中国'},"

18 + "{name:'梁朝伟',age:'53',country:'中国'},"

19 + "{name:'成龙',age:'61',country:'中国'}]";20 @Override21 protected voidonCreate(Bundle savedInstanceState) {22 super.onCreate(savedInstanceState);23 setContentView(R.layout.activity_main);24 tv_name =(TextView) findViewById(R.id.tv_name);25 tv_age =(TextView) findViewById(R.id.tv_age);26 tv_country =(TextView) findViewById(R.id.tv_country);27 try{28 JSONArray jsonArray = newJSONArray(jsonArrStr);29 for (int i = 0; i < 3; i++) {30 System.out.println(jsonArray.get(i).toString());31 }32 JSONObject jsonObject = new JSONObject(jsonArray.get(0).toString());33 String name = jsonObject.getString("name");34 String age = jsonObject.getString("age");35 String country = jsonObject.getString("country");36

37 tv_name.setText(name);38 tv_name.setTextSize(25);39 tv_age.setText(age);40 tv_age.setTextSize(25);41 tv_country.setText(country);42 tv_country.setTextSize(25);43 } catch(JSONException e) {44 //TODO 自动生成的 catch 块

45 e.printStackTrace();46 }47

48 }49

50

51 }

(4)布署程序到模拟器上,如下:

833db21c3f2151dc80c923fda18e7798.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值