Android移動(dòng)應(yīng)用開發(fā)-網(wǎng)絡(luò)連接與管理_第1頁(yè)
Android移動(dòng)應(yīng)用開發(fā)-網(wǎng)絡(luò)連接與管理_第2頁(yè)
Android移動(dòng)應(yīng)用開發(fā)-網(wǎng)絡(luò)連接與管理_第3頁(yè)
Android移動(dòng)應(yīng)用開發(fā)-網(wǎng)絡(luò)連接與管理_第4頁(yè)
Android移動(dòng)應(yīng)用開發(fā)-網(wǎng)絡(luò)連接與管理_第5頁(yè)
已閱讀5頁(yè),還剩55頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Android移動(dòng)應(yīng)用開發(fā)

010302040706認(rèn)識(shí)Android列表與適配器菜單與對(duì)話框設(shè)計(jì)UI控件設(shè)計(jì)設(shè)計(jì)用戶界面創(chuàng)建Android項(xiàng)目Android本地存儲(chǔ)書目錄140911BroadcastReceiver與廣播通信Service與后臺(tái)服務(wù)設(shè)計(jì)ContentProvider與應(yīng)用間數(shù)據(jù)共享網(wǎng)絡(luò)連接與管理05Activity與Fragment08131210線程間的通信與異步機(jī)制Android性能分析與測(cè)試

網(wǎng)絡(luò)連接與管理13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問(wèn)網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.1.1初識(shí)ConnectivityManagerConnectivityManager的主要作用如下。監(jiān)聽手機(jī)網(wǎng)絡(luò)的狀態(tài),包括通用分組無(wú)線業(yè)務(wù)(GeneralPacketRadioService,GPRS)、Wi-Fi、通用移動(dòng)通信系統(tǒng)(UniversalMobileTelecommunicationsSystem,UMTS)等。網(wǎng)絡(luò)狀態(tài)發(fā)生改變時(shí)發(fā)送廣播。當(dāng)一個(gè)網(wǎng)絡(luò)連接失敗時(shí)進(jìn)行故障切換(嘗試連接到其他的網(wǎng)絡(luò))。為應(yīng)用查詢網(wǎng)絡(luò)狀態(tài)提供API接口。ConnectivityManager是包提供的用于管理與網(wǎng)絡(luò)連接相關(guān)的操作類,可以實(shí)現(xiàn)查詢網(wǎng)絡(luò)連接狀態(tài)、當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生改變時(shí)通知應(yīng)用等操作。13.1.1初識(shí)ConnectivityManagerConnectivityManager提供以下幾個(gè)主要方法。NetworkInfogetActiveNetworkInfo()NetworkInfo[]getAllNetworkInfo()NetworkInfogetNetworkInfo()intgetNetworkPreference()booleanisActiveNetworkMetered()staticbooleanisNetworkTypeValid()初始化一個(gè)ConnectivityManager的方法如下。ConnectivityManagerconnectivityManager=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);13.1.2網(wǎng)絡(luò)接入管理網(wǎng)絡(luò)可用判斷方法1:publicstaticbooleanisNetworkAvailable(Contextcontext){ConnectivityManagerconnectivity=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);if(connectivity==null){Log.w(LOG_TAG,"couldn'tgetconnectivitymanager");}else{NetworkInfo[]info=connectivity.getAllNetworkInfo();if(info!=null){for(inti=0;i<info.length;i++){if(info[i].isAvailable()){Log.d(LOG_TAG,"networkisavailable");returntrue;}}}}Log.d(LOG_TAG,"networkisnotavailable");returnfalse;}13.1.2網(wǎng)絡(luò)接入管理NetworkInfo提供以下幾個(gè)重要的方法。getState():獲取代表連接成功與否等狀態(tài)的State對(duì)象。getDetailedState():獲取詳細(xì)狀態(tài)信息。getExtraInfo():獲取附加信息。getReason():獲取連接失敗的原因。getType():獲取網(wǎng)絡(luò)類型(一般為Wi-Fi或移動(dòng)網(wǎng)絡(luò))。getTypeName():獲取網(wǎng)絡(luò)類型名稱(一般取值為WI-FI或MOBILE)。isAvailable():判斷該網(wǎng)絡(luò)是否可用。isConnected():判斷是否已經(jīng)連接可用網(wǎng)絡(luò)。isConnectedOrConnecting():判斷是否已經(jīng)連接或正在連接可用網(wǎng)絡(luò)。isFailover():判斷是否連接失敗。isRoaming():判斷是否漫游。13.1.2網(wǎng)絡(luò)接入管理網(wǎng)絡(luò)可用判斷方法2:publicstaticbooleanisNetworkAvailable(Contextcontext){ConnectivityManagerconnectivity=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);if(connectivity==null){Log.w(LOG_TAG,"couldn'tgetconnectivitymanager");}else{NetworkInfoactiveNetwork=connectivity.getActiveNetworkInfo();}returnactiveNetwork.isConnectedOrConnecting();}13.1.2網(wǎng)絡(luò)接入管理網(wǎng)絡(luò)連接判斷在確定有可用網(wǎng)絡(luò)的前提下,還需要檢查網(wǎng)絡(luò)是否連接,方法如下。publicstaticbooleancheckNetState(Contextcontext){booleannetstate=false;ConnectivityManagerconnectivity=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);if(connectivity!=null){NetworkInfo[]info=connectivity.getAllNetworkInfo();if(info!=null){for(inti=0;i<info.length;i++){if(info[i].getState()==NetworkInfo.State.CONNECTED){netstate=true;break;}}}}returnnetstate;}13.1.2網(wǎng)絡(luò)接入管理還可以使用如下方法打開網(wǎng)絡(luò)設(shè)置界面。publicstaticvoidsetNetworkMethod(finalContextcontext){AlertDialog.Builderbuilder=newBuilder(context);builder.setTitle("網(wǎng)絡(luò)設(shè)置提示").setMessage("網(wǎng)絡(luò)連接不可用,是否進(jìn)行設(shè)置?").setPositiveButton("設(shè)置",newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intwhich){Intentintent=null;if(android.os.Build.VERSION.SDK_INT>10){intent=newIntent(vider.Settings.ACTION_WIRELESS_SETTINGS);} else{intent=newIntent();ComponentNamecomponent=newComponentName("com.android.settings","com.android.settings.WirelessSettings");intent.setComponent(component);intent.setAction("ent.action.VIEW");}context.startActivity(intent);}}).setNegativeButton("取消",newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intwhich){dialog.dismiss();}}).show();}13.1.3監(jiān)聽網(wǎng)絡(luò)連接狀態(tài)Android的網(wǎng)絡(luò)連接狀態(tài)監(jiān)聽可以用BroadcastReceiver來(lái)接收網(wǎng)絡(luò)連接狀態(tài)改變的廣播,具體實(shí)現(xiàn)步驟如下。312定義一個(gè)BroadcastReceiver,并重載其中的onReceive()方法,在其中完成監(jiān)聽網(wǎng)絡(luò)連接狀態(tài)的功能。只要網(wǎng)絡(luò)的連接狀態(tài)發(fā)生變化,ConnectivityManager就會(huì)立刻發(fā)送廣播CONNECTIVITY_ACTION。因此,需要在適當(dāng)?shù)奈恢米?cè)BroadcastReceiver。在適當(dāng)?shù)奈恢萌∠?cè)BroadcastReceiver。13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問(wèn)網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.2.1HTTPA支持客戶端/服務(wù)器模式。B簡(jiǎn)單快速:客戶端向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。C靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象(類型由Content-Type加以標(biāo)記)。D無(wú)連接:即每次連接只處理一個(gè)請(qǐng)求,處理完客戶端的請(qǐng)求并收到客戶端的應(yīng)答后就斷開連接??梢怨?jié)省傳輸時(shí)間。E無(wú)狀態(tài):無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。HTTP的特點(diǎn)與分類HTTP的主要特點(diǎn)如下。13.2.1HTTPHTTP1.0客戶端在每次向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器就會(huì)向客戶端返回響應(yīng)消息(包括請(qǐng)求是否正確及所請(qǐng)求的數(shù)據(jù)),在確認(rèn)客戶端已經(jīng)收到響應(yīng)消息后,服務(wù)器就會(huì)關(guān)閉網(wǎng)絡(luò)連接(關(guān)閉TCP連接)。HTTP1.1客戶端連接到服務(wù)器后,服務(wù)器就將關(guān)閉客戶端連接的主動(dòng)權(quán)交還給客戶端。HTTP包括以下兩種。13.2.1HTTPHTTP請(qǐng)求/響應(yīng)的組成HTTP消息由客戶端到服務(wù)器的請(qǐng)求消息和服務(wù)器到客戶端的響應(yīng)消息組成。請(qǐng)求消息和響應(yīng)消息都是由開始行(對(duì)于請(qǐng)求消息,開始行就是請(qǐng)求行;對(duì)于響應(yīng)消息,開始行就是狀態(tài)行)、消息報(bào)頭(可選)、空行(只有CRLF的行)、消息正文(可選)組成的。(1)請(qǐng)求行MethodRequest-URIHTTP-VersionCRLF請(qǐng)求行以一個(gè)方法符號(hào)開頭,以空格分開,后面跟著請(qǐng)求的URI和協(xié)議的版本,格式如下。13.2.1HTTP表13-1HTTP請(qǐng)求方法說(shuō)明請(qǐng)求方法說(shuō)明GET請(qǐng)求獲取Request-URI所標(biāo)識(shí)的資源POST在Request-URI所標(biāo)識(shí)的資源后附加新的數(shù)據(jù)HEAD請(qǐng)求獲取由Request-URI所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭PUT請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用Request-URI作為其標(biāo)識(shí)DELETE請(qǐng)求服務(wù)器刪除Request-URI所標(biāo)識(shí)的資源TRACE請(qǐng)求服務(wù)器回送收到的請(qǐng)求信息,主要用于測(cè)試或診斷CONNECT保留將來(lái)使用OPTIONS請(qǐng)求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項(xiàng)和需求13.2.1HTTP狀態(tài)行包括HTTP版本號(hào)、狀態(tài)碼及狀態(tài)碼的文本描述信息。狀態(tài)碼由一個(gè)3位數(shù)組成,大體有以下5種含義。1××:信息提示。100表示請(qǐng)求收到,繼續(xù)處理。2××:成功。200表示請(qǐng)求成功,206表示斷點(diǎn)續(xù)傳。3××:重定向。一般跳轉(zhuǎn)到新的地址。4××:客戶端錯(cuò)誤。404表示文件不存在。5××:服務(wù)器錯(cuò)誤。500表示內(nèi)部錯(cuò)誤。(2)狀態(tài)行HTTP消息報(bào)頭包括請(qǐng)求報(bào)頭、響應(yīng)報(bào)頭、實(shí)體報(bào)頭。(3)消息報(bào)頭13.2.2HttpURLConnection的特點(diǎn)HttpURLConnection的特點(diǎn)如下。AHttpURLConnection是AndroidSDK的標(biāo)準(zhǔn)實(shí)現(xiàn)。BHttpURLConnection直接支持GZIP壓縮。CHttpURLConnection直接支持系統(tǒng)級(jí)連接池,即打開的連接不會(huì)直接關(guān)閉,在一段時(shí)間內(nèi)所有程序可共用。DHttpURLConnection直接在系統(tǒng)層面做了緩存策略處理,加快重復(fù)請(qǐng)求的速度。13.2.3創(chuàng)建HttpURLConnection連接通常創(chuàng)建一個(gè)和URL連接,并發(fā)送請(qǐng)求、讀取此URL引用的資源需要以下幾個(gè)步驟。-÷×+通過(guò)URL對(duì)象的openConnection()方法來(lái)創(chuàng)建URLConnection對(duì)象。設(shè)置URLConnection的參數(shù)和普通請(qǐng)求屬性。如果是發(fā)送GET方式的請(qǐng)求,使用connect()方法建立和遠(yuǎn)程資源之間的實(shí)際連接即可;遠(yuǎn)程資源變?yōu)榭捎?,程序可以訪問(wèn)遠(yuǎn)程資源的頭字段,或通過(guò)輸入流來(lái)讀取遠(yuǎn)程資源的數(shù)據(jù)。13.2.3創(chuàng)建HttpURLConnection連接創(chuàng)建HttpURLConnection對(duì)象HttpURLConnection是一種訪問(wèn)HTTP資源的方式。HttpURLConnection是一個(gè)抽象類,不能通過(guò)newHttpURLConnection()方法來(lái)獲取一個(gè)HttpURLConnection對(duì)象。常見的做法是使用.URL封裝HTTP資源的URL,并使用openConnection()方法獲得HttpURLConnection對(duì)象。例如:try{URLurl=newURL(httpUrl);URLConnectionurlConnection=url.openConnection();HttpURLConnectionhttpUrlConnection=(HttpURLConnection)urlConnection;}catch(MalformedURLExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}13.2.3創(chuàng)建HttpURLConnection連接設(shè)置HttpURLConnection參數(shù)HttpURLConnectionAPI提供了一系列的set方法來(lái)設(shè)置網(wǎng)絡(luò)連接的參數(shù),主要如下。voidsetConnectTimeout(inttimeout)voidsetRequestMethod(Stringmethod)voidsetDoInput(booleandoinput)voidsetDoOutput(booleandooutput)voidsetDefaultUseCaches(booleandefaultusecaches)voidsetUseCaches(booleanusecaches)voidsetRequestProperty(Stringkey,Stringvalue)staticvoidsetContentHandlerFactory(ContentHandlerFactoryfac)staticvoidsetDefaultAllowUserInteraction(booleandefaultallowuserinteraction)voidsetChunkedStreamingMode(intchunklen)voidsetFixedLengthStreamingMode(intcontentLength)13.2.3創(chuàng)建HttpURLConnection連接A一般需要通過(guò)setConnectTimeout()方法設(shè)置連接超時(shí),如果網(wǎng)絡(luò)不好,Android在超過(guò)默認(rèn)時(shí)間后會(huì)收回資源中斷操作。B通過(guò)getResponseCode()方法對(duì)狀態(tài)碼進(jìn)行判斷,如果返回的狀態(tài)碼為200,則表示連接成功。C在對(duì)大文件進(jìn)行操作時(shí),要將文件寫到存儲(chǔ)卡上,不要直接寫到手機(jī)內(nèi)存上。D操作大文件時(shí),要一邊從網(wǎng)絡(luò)上讀取,一邊往存儲(chǔ)卡上寫入,減少手機(jī)內(nèi)存的使用。E對(duì)文件流操作完畢后要記得及時(shí)關(guān)閉流對(duì)象。進(jìn)行HttpURLConnection連接設(shè)置好HttpURLConnection的連接參數(shù)后,即可通過(guò)connect()方法進(jìn)行網(wǎng)絡(luò)連接。如果在已打開連接(此時(shí)connected屬性值為true)的情況下調(diào)用connect()方法,則忽略該調(diào)用。調(diào)用disconnect()方法斷開連接。使用HttpURLConnection進(jìn)行網(wǎng)絡(luò)連接時(shí)需要注意以下幾點(diǎn)。13.2.4HttpURLConnection數(shù)據(jù)交換HttpURLConnectionAPI提供了一系列的get方法來(lái)獲取網(wǎng)絡(luò)傳遞的信息,主要如下。get方法作用ObjectgetContent()獲取該URLConnection的內(nèi)容。StringgetHeaderField()獲取指定響應(yīng)頭字段的值。InputStreamgetInputStream()返回從此打開的連接讀取的輸入流。OutputStreamgetOutputStream()返回寫入此連接的輸出流。intgetResponseCode()從HTTP響應(yīng)消息獲取狀態(tài)碼。StringgetResponseMessage()獲取與來(lái)自服務(wù)器的響應(yīng)代碼一起返回的HTTP響應(yīng)消息(如果有)。InputStreamgetErrorStream()如果連接失敗但服務(wù)器仍然發(fā)送了有用數(shù)據(jù),則返回錯(cuò)誤流。13.2.4HttpURLConnection數(shù)據(jù)交換下面列舉幾個(gè)常見的用法。使用POST方式請(qǐng)求數(shù)據(jù)使用POST方式請(qǐng)求數(shù)據(jù)的一般步驟如下。確定URL,一般為URI。確定請(qǐng)求參數(shù)。

通過(guò)URL創(chuàng)建HttpURLConnection對(duì)象。HttpURLConnection設(shè)置連接可讀寫數(shù)據(jù)。通過(guò)getOutputStream()方法獲得輸出流對(duì)象,進(jìn)而發(fā)送請(qǐng)求參數(shù)。13.2.4HttpURLConnection數(shù)據(jù)交換下面的代碼演示了使用POST方式請(qǐng)求數(shù)據(jù)的過(guò)程。publicstaticStringdoPost(Stringurl,Stringparam){PrintWriterout=null;BufferedReaderin=null;Stringresult="";try{URLrealUrl=newURL(url);//打開和URL之間的連接HttpURLConnectionconn=(HttpURLConnection)realUrl.openConnection();//設(shè)置通用的請(qǐng)求屬性conn.setRequestProperty("accept","*/*");conn.setRequestProperty("connection","Keep-Alive");conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");conn.setRequestProperty("charset","utf-8");conn.setUseCaches(false);//發(fā)送POST請(qǐng)求必須設(shè)置如下兩行conn.setDoOutput(true);conn.setDoInput(true);conn.setReadTimeout(TIMEOUT_IN_MILLIONS);conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);13.2.4HttpURLConnection數(shù)據(jù)交換if(param!=null&&!param.trim().equals("")){//獲取URLConnection對(duì)象對(duì)應(yīng)的輸出流out=newPrintWriter(conn.getOutputStream());//發(fā)送請(qǐng)求參數(shù)out.print(param);//flush輸出流的緩沖out.flush();}//定義BufferedReader輸入流來(lái)讀取URL的響應(yīng)in=newBufferedReader(newInputStreamReader(conn.getInputStream()));Stringline;while((line=in.readLine())!=null){result+=line;}}catch(Exceptione){e.printStackTrace();}//使用finally塊來(lái)關(guān)閉輸出流、輸入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOExceptionex){ex.printStackTrace();}}returnresult;}13.2.4HttpURLConnection數(shù)據(jù)交換使用GET方式請(qǐng)求數(shù)據(jù)使用GET方式請(qǐng)求數(shù)據(jù)的一般步驟如下。確定URL,一般結(jié)構(gòu)為url+"?"+params。通過(guò)URL調(diào)用openConnection()方法創(chuàng)建HttpURLConnection對(duì)象。HttpURLConnection對(duì)象調(diào)用setConnectTimeout()方法設(shè)置網(wǎng)絡(luò)響應(yīng)時(shí)間,調(diào)用setRequestMethod()方法設(shè)置發(fā)送請(qǐng)求的方法。通過(guò)getInputStream()方法獲得輸入流,進(jìn)而獲得響應(yīng)。13.2.4HttpURLConnection數(shù)據(jù)交換下面的代碼演示了使用GET方式請(qǐng)求數(shù)據(jù)的過(guò)程。publicstaticStringdoGet(StringurlStr){URLurl=null;HttpURLConnectionconn=null;InputStreamis=null;ByteArrayOutputStreambaos=null;try{url=newURL(urlStr);conn=(HttpURLConnection)url.openConnection();conn.setReadTimeout(TIMEOUT_IN_MILLIONS);conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);conn.setRequestMethod("GET");conn.setRequestProperty("accept","*/*");conn.setRequestProperty("connection","Keep-Alive");if(conn.getResponseCode()==200){is=conn.getInputStream();baos=newByteArrayOutputStream();intlen=-1;byte[]buf=newbyte[128];while((len=is.read(buf))!=-1){baos.write(buf,0,len);}baos.flush();returnbaos.toString();}else{thrownewRuntimeException("responseCodeisnot200…");}}catch(Exceptione){e.printStackTrace();}finally{try{if(is!=null)is.close();}catch(IOExceptione){}try{if(baos!=null)baos.close();}catch(IOExceptione){}conn.disconnect();}returnnull;}13.2.4HttpURLConnection數(shù)據(jù)交換在使用HttpURLConnection進(jìn)行數(shù)據(jù)交換時(shí),需要注意以下事項(xiàng)。上傳數(shù)據(jù)至服務(wù)器(向服務(wù)器發(fā)送請(qǐng)求)時(shí),如果知道上傳數(shù)據(jù)的大小,則應(yīng)顯式使用setFixedLengthStreamingMode()方法來(lái)設(shè)置上傳數(shù)據(jù)的精確值;如果不知道上傳數(shù)據(jù)的大小,則應(yīng)使用setChunkedStreamingMode()方法(通常使用默認(rèn)值0作為實(shí)際參數(shù)傳入)。如果兩個(gè)方法都未設(shè)置,則系統(tǒng)會(huì)強(qiáng)制將請(qǐng)求體中的所有內(nèi)容都緩存至內(nèi)存中(在通過(guò)網(wǎng)絡(luò)進(jìn)行傳輸之前),這樣會(huì)浪費(fèi)堆內(nèi)存(甚至可能耗盡),并加重隱患。如果通過(guò)流輸入或輸出少量數(shù)據(jù),則需要使用帶緩沖區(qū)的流(如BufferedInputStream);大量讀取或輸出數(shù)據(jù)時(shí),可忽略緩沖流(不使用緩沖流會(huì)增加磁盤輸入/輸出,默認(rèn)的流操作是直接進(jìn)行磁盤輸入/輸出的)。當(dāng)需要傳輸(輸入或輸出)大量數(shù)據(jù)時(shí),使用“流”來(lái)限制內(nèi)存中的數(shù)據(jù)量,即將數(shù)據(jù)直接放在“流”中,而不是放在字節(jié)數(shù)組或字符串中(這些都存儲(chǔ)在內(nèi)存中)。任務(wù)13.1實(shí)現(xiàn)音樂播放器搜索網(wǎng)絡(luò)音樂【任務(wù)介紹】1.任務(wù)描述實(shí)現(xiàn)音樂播放器搜索網(wǎng)絡(luò)音樂的功能,并實(shí)現(xiàn)對(duì)搜索結(jié)果的播放。2.運(yùn)行結(jié)果本任務(wù)運(yùn)行結(jié)果如圖所示。13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問(wèn)網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.3.1JSON與XML對(duì)比所以,JSON和XML的輕/重量級(jí)的區(qū)別在于:JSON只提供整體解析方案,而這種方案只在解析較少的數(shù)據(jù)時(shí)才能達(dá)到良好的效果;XML提供對(duì)大規(guī)模數(shù)據(jù)的逐步解析方案,這種方案適用于對(duì)大量數(shù)據(jù)的處理。

解析方式XML目前設(shè)計(jì)了兩種解析方式:DOM和SAX。DOM是把一個(gè)數(shù)據(jù)交換格式XML看成一個(gè)DOM對(duì)象,需要把整個(gè)XML文件讀入內(nèi)存,這一點(diǎn)上JSON和XML的原理是一樣的。但是XML要考慮父節(jié)點(diǎn)和子節(jié)點(diǎn),這一點(diǎn)上JSON的解析難度要小很多,因?yàn)镴SON構(gòu)建于兩種結(jié)構(gòu)——鍵值對(duì)的集合、值的有序列表,可理解為數(shù)組。SAX不需要讀入整個(gè)文件就可以對(duì)解析出的內(nèi)容進(jìn)行處理,是一種逐步解析的方法。程序也可以隨時(shí)終止解析。13.3.1JSON與XML對(duì)比從主觀來(lái)看JSON更為清晰且冗余更少。JSON網(wǎng)站提供了對(duì)JSON語(yǔ)法的嚴(yán)格描述,只是描述較簡(jiǎn)短。從總體來(lái)看XML比較適于標(biāo)記文檔,而JSON卻更適于進(jìn)行數(shù)據(jù)交換處理。編碼13.3.1JSON與XML對(duì)比傳輸速度JSON相對(duì)XML來(lái)說(shuō),數(shù)據(jù)的文件量小,傳遞的速度更快。XML格式代碼如下。<?xmlversion="1.0"encoding="utf-8"?><country><name>中國(guó)</name><province><name>黑龍江</name><citys><city>哈爾濱</city><city>大慶</city></citys></province><province><name>廣東</name><citys><city>廣州</city><city>深圳</city><city>珠海</city></citys></province><province><name>臺(tái)灣</name><citys><city>臺(tái)北</city><city>高雄</city></citys></province><province><name>新疆</name><citys><city>烏魯木齊</city></citys></province></country>13.3.1JSON與XML對(duì)比JSON格式代碼如下。varcountry={name:"中國(guó)",provinces:[{name:"黑龍江",citys:{city:["哈爾濱","大慶"]}},{name:"廣東",citys:{city:["廣州","深圳","珠海"]}},{name:"臺(tái)灣",citys:{city:["臺(tái)北","高雄"]}},{name:"新疆",citys:{city:["烏魯木齊"]}}]}13.3.2JSON數(shù)據(jù)結(jié)構(gòu)JSON有以下兩種數(shù)據(jù)結(jié)構(gòu)。JSON也是基于純文本的數(shù)據(jù)結(jié)構(gòu)(JSON文件的文件類型是.json,JSON文本的MIME類型是application/json)。鍵值對(duì)的集合。在不同的編程語(yǔ)言中,它被理解為對(duì)象(Object)、記錄(Record)、結(jié)構(gòu)(Struct)、字典(Dictionary)、哈希表(HashTable)、有鍵列表(KeyedList)或者關(guān)聯(lián)數(shù)組(AssociativeArray)。值的有序列表。在大部分編程語(yǔ)言中,它被實(shí)現(xiàn)為數(shù)組(Array)、矢量(Vector)、列表(List)、序列(Sequence)。13.3.2JSON數(shù)據(jù)結(jié)構(gòu)JSON的常見數(shù)據(jù)形式有以下5種。對(duì)象一個(gè)對(duì)象以“{”開始,并以“}”結(jié)束,如圖13-2所示。一個(gè)對(duì)象包含一系列非排序的鍵值對(duì),每個(gè)鍵值對(duì)之間使用逗號(hào)分隔。此處的對(duì)象相當(dāng)于Java中的Map<String,Object>,而不是Java中的Class。例如,一個(gè)Address對(duì)象包含如下鍵值對(duì)。{"city":"Beijing","street":"ChaoyangRoad","postcode":100025}13.3.2JSON數(shù)據(jù)結(jié)構(gòu)值值可以是雙引號(hào)標(biāo)注的字符串、數(shù)值、對(duì)象、數(shù)組、布爾值(true、false)或null,如圖所示。這些結(jié)構(gòu)可以嵌套。13.3.2JSON數(shù)據(jù)結(jié)構(gòu)數(shù)組數(shù)組使用[]包含所有元素,兩個(gè)元素之間用逗號(hào)分隔,如圖所示。元素可以是任意的值。例如,以下數(shù)組包含一個(gè)字符串、數(shù)值、布爾值和一個(gè)null。{"people":[{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}]}13.3.2JSON數(shù)據(jù)結(jié)構(gòu)字符串字符串是以雙引號(hào)標(biāo)注的一串字符,如圖所示。除了部分字符("、\、/)和一些控制字符(\b、\f、\n、\r、\t)需要編碼外,其他Unicode字符可以直接輸出。13.3.2JSON數(shù)據(jù)結(jié)構(gòu)數(shù)值數(shù)值是一系列0~9的數(shù)字組合,可以為負(fù)數(shù)或者小數(shù),還可以用“e”或者“E”表示為指數(shù)形式,如圖13-6所示。13.3.3解析JSON-÷×+JSONObject是一個(gè)無(wú)序的鍵值對(duì)的集合,可以看作一個(gè)JSON對(duì)象,這是系統(tǒng)中有關(guān)JSON定義的基本單元。它的外在形式是一個(gè)用花括號(hào)標(biāo)注,并用冒號(hào)將名字和值分開的字符串,內(nèi)部形式就是一個(gè)對(duì)象。JSONObject提供了一系列的get、set和opt方法來(lái)訪問(wèn)JSONObject實(shí)例。對(duì)JSONObject有兩個(gè)不同的取值方法。getType()optType()方法JSONObject13.3.3解析JSON下面的代碼用于創(chuàng)建一個(gè)JSONObject對(duì)象。privateJSONObjectcreateJSONObject(){JSONObjectperson=newJSONObject();try{JSONArrayphone=newJSONArray();phone.put("12345678");phone.put("87654321");person.put("phone",phone);person.put("name","liweiyong");person.put("age",100);JSONObjectaddress=newJSONObject();address.put("country","china");address.put("province","jiangsu");person.put("address",address);person.put("married",false);}catch(JSONExceptione){e.printStackTrace();}returnperson;}創(chuàng)建的JSONObject對(duì)象形式如下。{"phone":["12345678","87654321"], //數(shù)組"married":false, //布爾值"address":{"province":"jiangsu","country":"china"}, //JSON對(duì)象"age":100, //數(shù)值"name":"liweiyong" //字符串}13.3.3解析JSONJSONStringerJSONStringer是JSON文本構(gòu)建類,用于幫助快速和便捷地創(chuàng)建JSON文本。其最大的優(yōu)點(diǎn)在于可以減少因格式的錯(cuò)誤而導(dǎo)致程序異常,引用這個(gè)類可以自動(dòng)嚴(yán)格按照J(rèn)SON語(yǔ)法規(guī)則創(chuàng)建JSON文本。每個(gè)JSONStringer實(shí)體只能對(duì)應(yīng)創(chuàng)建一個(gè)JSON文本。例如:try{StringmyString=newJSONStringer().object().key("id").value("20120226").key("name").value("lxb").endObject().toString();}catch(JSONExceptionex){thrownewRuntimeException(ex);}13.3.3解析JSONJSONArrayJSONArray代表一組有序的數(shù)值。表現(xiàn)形式是用方括號(hào)標(biāo)注,數(shù)值以逗號(hào)分隔(例如[value1,value2,value3])。下面的代碼是對(duì)JSONArray遍歷的典型方式。JSONArrayarray=JSONArray.fromObject(data);for(Objectobject:array){JSONObjecto=JSONObject.fromObject(object);o.get("key")}13.3.3解析JSONJSONTokenerJSONTokener是系統(tǒng)為JSONObject和JSONArray構(gòu)造的解析類,它可以從源信息中提取數(shù)值信息。例如:privatestaticStringgetJSONContent(){JSONTokenerjsonTokener=newJSONTokener(JSONText);JSONObjectstudentJSONObject;Stringname=null;intid=0;Stringphone=null;try{studentJSONObject=(JSONObject)jsonTokener.nextValue();name=studentJSONObject.getString("name");id=studentJSONObject.getInt("id");phone=studentJSONObject.getString("phone");}catch(JSONExceptione){e.printStackTrace();}returnname+""+id+""+phone;}13.3.3解析JSONJSONExceptionJSONException是類拋出的異常信息。以下情況下會(huì)產(chǎn)生JSONException。試圖解析或構(gòu)建一個(gè)格式錯(cuò)誤的JSON文檔。使用null作為關(guān)鍵詞。使用JSON不支持的數(shù)值類型,如NaN或無(wú)窮大的值。使用不存在的鍵進(jìn)行查找。解析的類型不匹配。13.3.3解析JSONJSONStringJSONString是一個(gè)接口,以便其他類可以通過(guò)實(shí)現(xiàn)該接口的toString()方法來(lái)改變JSONObject、JSONArray等內(nèi)部toString()方法的功能,以實(shí)現(xiàn)它們自己的序列化。JSONWriterJSONWriter位于android.util包下,是一個(gè)快速將JSON文本寫入數(shù)據(jù)流的工具。每次只能輸出一個(gè)字符串。流中既包括字符串、數(shù)值、布爾值和空值,也包括作為對(duì)象、數(shù)組的開始和結(jié)束標(biāo)志的分隔符。13.3.3解析JSON下面的writeJsonStream()方法主要利用JsonWriter把聯(lián)系人的信息寫入文件流。privatevoidwriteJsonStream(){ByteArrayOutputStreamout=newByteArrayOutputStream();JsonWriterwriter=newJsonWriter(newOutputStreamWriter(out,"UTF-8"));Cursorcur=context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,null, ContactsContract.Contacts.DISPLAY_NAME+"COLLATELOCALIZEDASC");if(cur!=null&&cur.moveToFirst()){intidColumn=cur.getColumnIndex(ContactsContract.Contacts._ID);intdisplayNameColumn=cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);writer.setIndent("");writer.beginObject();(ContactStruct.CONTACTS);writer.beginArray();do{writer.beginObject();StringcontactId=cur.getString(idColumn);(ContactStruct._ID).value(contactId);StringdisPlayName=cur.getString(displayNameColumn);(ContactStruct.NAME).value(disPlayName);intphoneCount=cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));Log.i("username",disPlayName);13.3.3解析JSONif(phoneCount>0){Cursorphones=context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contactId,null,null);if(phones!=null&&phones.moveToFirst()){(ContactStruct.PHONENUMBERS);writer.beginArray();do{writer.beginObject();StringphoneNumber=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));StringphoneType=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));(ContactStruct.TYPE).value(phoneType);(ContactStruct.PHONENUMBER).value(phoneNumber);writer.endObject();Log.i("phoneNumber",phoneNumber+"");Log.i("phoneType",phoneType+"");}while(phones.moveToNext());writer.endArray();}closeCursor(phones);}}while(cur.moveToNext());}}13.3.3解析JSONJSONReaderJsonReader位于android.util包下,主要用來(lái)讀取JSON字符串的內(nèi)容。例如,JSON字符串如下。privatestaticfinalStringJSONString="[{\"name\":\"Michael\",\"age\":20},{\"name\":\"Mike\",\"age\":21}]";在Activity中調(diào)用解析方法。JSONUtilsjsonUtils=newJSONUtils();jsonUtils.parseJson(JSONString);13.3.3解析JSON其中的JSONUtils代碼如下。publicclassJSONUtils{publicvoidparseJson(StringjsonData){try{JsonReaderreader=newJsonReader(newStringReader(jsonData));reader.beginArray();while(reader.hasNext()){reader.beginObject();while(reader.hasNext()){StringtagName=reader.nextName();if(tagName.equals("name")){System.out.println("name--->"+reader.nextString());}elseif(tagName.equals("age")){System.out.println("age--->"+reader.nextInt());}}reader.endObject();}reader.endArray();}catch(Exceptione){e.printStackTrace();}}}“Logcat”窗口中的運(yùn)行結(jié)果13.3.3解析JSON演示一個(gè)向中國(guó)天氣網(wǎng)發(fā)送獲取天氣信息的請(qǐng)求,然后解析獲取的JSON數(shù)據(jù)并顯示的示例。首先創(chuàng)建一個(gè)如下的請(qǐng)求連接工具類HttUtil,代碼如下。publicclassHttUtil{publicstaticHttpClienthttpClient=newDefaultHttpClient();/*@paramurl請(qǐng)求地址*@return服務(wù)器響應(yīng)的字符串*@throwsInterruptedException*@throwsExecutionException*/publicstaticStringgetRequest(finalStringurl)throwsInterruptedException,ExecutionException{FutureTask<String>task=newFutureTask<String>(newCallable<String>(){@OverridepublicStringcall()throwsException{HttpGetget=newHttpGet(url);

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論