在Android应用开发中,尤其是网络应用的开发,我们经常需要从网络上获取数据,而不仅仅从本地数据库或者本地文件中取得数据,这个时候就涉及到客户端与服务器端的数据交互了。客户端如何需要与服务器端进行数据交互,就需要约定一种协议或者是数据交换格式。那么一般的,Android客户端与服务器端进行数据交互有哪些方式呢?根据业务需求的不同,可能会选用不用的方式,通常有以下几种方式。
1)基于SOAP的Web服务(WebService)方式
Web服务是一种面向服务的架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。
根据W3C的定义,Web服务应当是一个软件系统,用以支持网络间不同机器的互动操作。网络服务通常是许多应用程序接口所组成的,它们通过网络,例如国际互联网的远程服务器端,执行客户所提交服务的请求。
Web服务是基于XML和HTTPS的一种服务,其通信协议主要基于SOAP,通过WSDL来描述服务,通过UDDI来发现和获得服务的元数据。
2)自定义XML数据格式的方式
除了使用标准的SOAP协议以外,项目组还可以自定义XML数据格式用来传递数据。比如项目可以约定如下XML格式,用来传递用户的数据信息。
<request> <type>1</type> <id>100000</id> <name>jname</name> <state>1</state> …… </request> |
3)JSON数据格式
JSON(JavascriptObjectNotation)是一种轻量级的资料交换语言,以文字为基础,且易于让人阅读。尽管JSON是在Javascript的一个子集,但JSON是独立于语言的文本格式,可以使用于任何语言。
JSON用于描述数据结构,有以下形式存在。
对象(object):一个对象以“{”开始,并以“}”结束。一个对象包含一系列非排序的名称/值对,每个名称/值对之间使用“,”分割。
名称/值对(collection):名称和值之间使用“:”隔开,一般的形式是:
{name:value}
一个名称是一个字符串;一个值可以是一个字符串,一个数值,一个对象,一个布林值,一个有序列表,或者一个null值。
值的有序列表(Array):一个或者多个值用“,”分割后,使用“[”,“]”括起来就形成了这样的列表,形如:
[collection,collection]
字符串:以""括起来的一串字符。
数值:一系列0-9的数字组合,可以为负数或者小数。还可以用“e”或者“E”表示为指数形式。
布尔值:表示为true 或者false。
下面的例子就能够清晰的说明JSON格式的结构。
{ "firstName":"John", "lastName":"Smith", "male":true, "age":25, "address": { "streetAddress":"21 2nd Street", "city":"New York", "state":"NY", "postalCode":"10021" }, "phoneNumber": [ { "type":"home", "number":"212 555-1234" }, { "type":"fax", "number":"646 555-4567" } ] } |
无论是Web服务的方式,还是自定义XML的方式,都是以XML格式为基础的。如今JSON数据格式已经在网络开发中越来越流行了,在很多场合都可以取代XML格式。这主要是因为JSON更适合网络数据的传输。那么,具体的,JSON数据格式与XML数据格式相比较,都有哪些优缺点呢。
使用XML作为传输格式的优势:
1)格式统一,符合标准。
2)容易与其他系统进行远程交互,数据共享比较方便。
使用XML格式的缺点:
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格式能够直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,但是完成的任务不变,且易于维护。
使用JSON格式的缺点:
1)没有XML格式这么推广的深入人心和使用广泛,没有XML那么通用性。
2)JSON格式目前在WebService中推广还属于初级阶段。
通过上面的对比我们可以看出,JSON是一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性,可以在不同平台间进行数据交换。为了节省内存,提高响应速度,在Android网络应用的开发中比较适合使用JSON格式。
AndroidSDK有一个包直接支持JSON格式的数据解析,都在org.json下,主要有以下几个类:
1)JSONObject
可以看作是一个JSON对象。这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。
2)JSONStringer
JSON文本构建类,根据官方的解释,这个类可以帮助快速和便捷的创建JSONtext。其最大的优点在于可以减少由于格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntaxrules)创建JSONtext。每个JSONStringer实体只能对应创建一个JSONtext。
3)JSONArray
它代表一组有序的数值。将其转换为String输出所表现的形式是用方括号包裹,数值以逗号”,”分隔(例如:[value1,value2,value3],大家可以亲自利用简短的代码更加直观的了解其格式)。
4)JSONTokener
JSON解析类。
5)JSONException
JSON解析过程中可能发生的异常。
下面我们就通过代码来说明如何在Android中对JSON数据进行解析。
假设我们已经可以从服务器端获取数据了,而且返回的JSON数据如下:
{"FLAG":"flag", "jobject":[ {"id":"100000","name":"jname","state":1}, {"id":"200000","name":"jname","state":2}]} |
下面的代码片段举例说明如何解析出FLAG对象和jobject对象。
/** *对JSON格式数据进行解析 */ publicvoid readJSON(String str){ try{ //转换为JSONObject JSONObjectresult = new JSONObject(str); Log.d("readJSON","FLAG = " + result.getString("FLAG")); //获取JSONArray数组 JSONArrayjsonArray = result.getJSONArray("jobject"); Log.d("readJSON","Numberof entries " + jsonArray.length()); for(int i = 0; i < jsonArray.length(); i++) { JSONObjectjsonObject = jsonArray.getJSONObject(i); Log.d("readJSON","id= " + jsonObject.getString("id")); Log.di("readJSON","name= " + jsonObject.getString("name")); Log.d("readJSON","state= " + jsonObject.getString("state")); } }catch (Exception e) { e.printStackTrace(); } } |
下面的代码片段说明了如何简单的构造一个JSON串。
/** *构造一个JSON格式的数据 */ publicString writeJSON() { JSONObjectobject = new JSONObject(); try{ object.put("id","100000"); object.put("name","jname"); object.put("state",new Integer(1)); }catch (JSONException e) { e.printStackTrace(); } Log.d("writeJSON",object.toString()); returnobject.toString(); } |
构造好的JSON串可以通过POST方式发送给服务器端,服务器端再进行解析,执行后续的业务流程。
图8-4展示了上面的示例代码的运行结果。
图8-4JSON读写结果图
通过上面的例子可以看出,在Android开发中,使用JSON格式的数据与服务器端交互还是非常方便的。
经验分享: 无论是采用JSON格式,还是自定义XML格式,客户端与服务器端传输的数据都是明文的,这样并不安全。所以,如果项目对数据安全性有一定的要求,务必要考虑做下加密解密的工作。 另外,由于Android的APK包很容易被反编译,如果单纯的使用Java来实现加密解密的代码,就很容易泄露具体算法。所以,如果项目中涉及到加密解密的操作,可以考虑使用JNI方式去做,这样被破解的可能性就小很多了。 |