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

下載本文檔

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

文檔簡介

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

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

網(wǎng)絡(luò)連接與管理13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.1.1初識ConnectivityManagerConnectivityManager的主要作用如下。監(jiān)聽手機(jī)網(wǎng)絡(luò)的狀態(tài),包括通用分組無線業(yè)務(wù)(GeneralPacketRadioService,GPRS)、Wi-Fi、通用移動通信系統(tǒng)(UniversalMobileTelecommunicationsSystem,UMTS)等。網(wǎng)絡(luò)狀態(tài)發(fā)生改變時發(fā)送廣播。當(dāng)一個網(wǎng)絡(luò)連接失敗時進(jìn)行故障切換(嘗試連接到其他的網(wǎng)絡(luò))。為應(yīng)用查詢網(wǎng)絡(luò)狀態(tài)提供API接口。ConnectivityManager是包提供的用于管理與網(wǎng)絡(luò)連接相關(guān)的操作類,可以實現(xiàn)查詢網(wǎng)絡(luò)連接狀態(tài)、當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生改變時通知應(yīng)用等操作。13.1.1初識ConnectivityManagerConnectivityManager提供以下幾個主要方法。NetworkInfogetActiveNetworkInfo()NetworkInfo[]getAllNetworkInfo()NetworkInfogetNetworkInfo()intgetNetworkPreference()booleanisActiveNetworkMetered()staticbooleanisNetworkTypeValid()初始化一個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提供以下幾個重要的方法。getState():獲取代表連接成功與否等狀態(tài)的State對象。getDetailedState():獲取詳細(xì)狀態(tài)信息。getExtraInfo():獲取附加信息。getReason():獲取連接失敗的原因。getType():獲取網(wǎng)絡(luò)類型(一般為Wi-Fi或移動網(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來接收網(wǎng)絡(luò)連接狀態(tài)改變的廣播,具體實現(xiàn)步驟如下。312定義一個BroadcastReceiver,并重載其中的onReceive()方法,在其中完成監(jiān)聽網(wǎng)絡(luò)連接狀態(tài)的功能。只要網(wǎng)絡(luò)的連接狀態(tài)發(fā)生變化,ConnectivityManager就會立刻發(fā)送廣播CONNECTIVITY_ACTION。因此,需要在適當(dāng)?shù)奈恢米訠roadcastReceiver。在適當(dāng)?shù)奈恢萌∠訠roadcastReceiver。13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.2.1HTTPA支持客戶端/服務(wù)器模式。B簡單快速:客戶端向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。C靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象(類型由Content-Type加以標(biāo)記)。D無連接:即每次連接只處理一個請求,處理完客戶端的請求并收到客戶端的應(yīng)答后就斷開連接??梢怨?jié)省傳輸時間。E無狀態(tài):無狀態(tài)是指協(xié)議對于事務(wù)處理沒有記憶能力。HTTP的特點與分類HTTP的主要特點如下。13.2.1HTTPHTTP1.0客戶端在每次向服務(wù)器發(fā)出請求后,服務(wù)器就會向客戶端返回響應(yīng)消息(包括請求是否正確及所請求的數(shù)據(jù)),在確認(rèn)客戶端已經(jīng)收到響應(yīng)消息后,服務(wù)器就會關(guān)閉網(wǎng)絡(luò)連接(關(guān)閉TCP連接)。HTTP1.1客戶端連接到服務(wù)器后,服務(wù)器就將關(guān)閉客戶端連接的主動權(quán)交還給客戶端。HTTP包括以下兩種。13.2.1HTTPHTTP請求/響應(yīng)的組成HTTP消息由客戶端到服務(wù)器的請求消息和服務(wù)器到客戶端的響應(yīng)消息組成。請求消息和響應(yīng)消息都是由開始行(對于請求消息,開始行就是請求行;對于響應(yīng)消息,開始行就是狀態(tài)行)、消息報頭(可選)、空行(只有CRLF的行)、消息正文(可選)組成的。(1)請求行MethodRequest-URIHTTP-VersionCRLF請求行以一個方法符號開頭,以空格分開,后面跟著請求的URI和協(xié)議的版本,格式如下。13.2.1HTTP表13-1HTTP請求方法說明請求方法說明GET請求獲取Request-URI所標(biāo)識的資源POST在Request-URI所標(biāo)識的資源后附加新的數(shù)據(jù)HEAD請求獲取由Request-URI所標(biāo)識的資源的響應(yīng)消息報頭PUT請求服務(wù)器存儲一個資源,并用Request-URI作為其標(biāo)識DELETE請求服務(wù)器刪除Request-URI所標(biāo)識的資源TRACE請求服務(wù)器回送收到的請求信息,主要用于測試或診斷CONNECT保留將來使用OPTIONS請求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項和需求13.2.1HTTP狀態(tài)行包括HTTP版本號、狀態(tài)碼及狀態(tài)碼的文本描述信息。狀態(tài)碼由一個3位數(shù)組成,大體有以下5種含義。1××:信息提示。100表示請求收到,繼續(xù)處理。2××:成功。200表示請求成功,206表示斷點續(xù)傳。3××:重定向。一般跳轉(zhuǎn)到新的地址。4××:客戶端錯誤。404表示文件不存在。5××:服務(wù)器錯誤。500表示內(nèi)部錯誤。(2)狀態(tài)行HTTP消息報頭包括請求報頭、響應(yīng)報頭、實體報頭。(3)消息報頭13.2.2HttpURLConnection的特點HttpURLConnection的特點如下。AHttpURLConnection是AndroidSDK的標(biāo)準(zhǔn)實現(xiàn)。BHttpURLConnection直接支持GZIP壓縮。CHttpURLConnection直接支持系統(tǒng)級連接池,即打開的連接不會直接關(guān)閉,在一段時間內(nèi)所有程序可共用。DHttpURLConnection直接在系統(tǒng)層面做了緩存策略處理,加快重復(fù)請求的速度。13.2.3創(chuàng)建HttpURLConnection連接通常創(chuàng)建一個和URL連接,并發(fā)送請求、讀取此URL引用的資源需要以下幾個步驟。-÷×+通過URL對象的openConnection()方法來創(chuàng)建URLConnection對象。設(shè)置URLConnection的參數(shù)和普通請求屬性。如果是發(fā)送GET方式的請求,使用connect()方法建立和遠(yuǎn)程資源之間的實際連接即可;遠(yuǎn)程資源變?yōu)榭捎茫绦蚩梢栽L問遠(yuǎn)程資源的頭字段,或通過輸入流來讀取遠(yuǎn)程資源的數(shù)據(jù)。13.2.3創(chuàng)建HttpURLConnection連接創(chuàng)建HttpURLConnection對象HttpURLConnection是一種訪問HTTP資源的方式。HttpURLConnection是一個抽象類,不能通過newHttpURLConnection()方法來獲取一個HttpURLConnection對象。常見的做法是使用.URL封裝HTTP資源的URL,并使用openConnection()方法獲得HttpURLConnection對象。例如: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方法來設(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一般需要通過setConnectTimeout()方法設(shè)置連接超時,如果網(wǎng)絡(luò)不好,Android在超過默認(rèn)時間后會收回資源中斷操作。B通過getResponseCode()方法對狀態(tài)碼進(jìn)行判斷,如果返回的狀態(tài)碼為200,則表示連接成功。C在對大文件進(jìn)行操作時,要將文件寫到存儲卡上,不要直接寫到手機(jī)內(nèi)存上。D操作大文件時,要一邊從網(wǎng)絡(luò)上讀取,一邊往存儲卡上寫入,減少手機(jī)內(nèi)存的使用。E對文件流操作完畢后要記得及時關(guān)閉流對象。進(jìn)行HttpURLConnection連接設(shè)置好HttpURLConnection的連接參數(shù)后,即可通過connect()方法進(jìn)行網(wǎng)絡(luò)連接。如果在已打開連接(此時connected屬性值為true)的情況下調(diào)用connect()方法,則忽略該調(diào)用。調(diào)用disconnect()方法斷開連接。使用HttpURLConnection進(jìn)行網(wǎng)絡(luò)連接時需要注意以下幾點。13.2.4HttpURLConnection數(shù)據(jù)交換HttpURLConnectionAPI提供了一系列的get方法來獲取網(wǎng)絡(luò)傳遞的信息,主要如下。get方法作用ObjectgetContent()獲取該URLConnection的內(nèi)容。StringgetHeaderField()獲取指定響應(yīng)頭字段的值。InputStreamgetInputStream()返回從此打開的連接讀取的輸入流。OutputStreamgetOutputStream()返回寫入此連接的輸出流。intgetResponseCode()從HTTP響應(yīng)消息獲取狀態(tài)碼。StringgetResponseMessage()獲取與來自服務(wù)器的響應(yīng)代碼一起返回的HTTP響應(yīng)消息(如果有)。InputStreamgetErrorStream()如果連接失敗但服務(wù)器仍然發(fā)送了有用數(shù)據(jù),則返回錯誤流。13.2.4HttpURLConnection數(shù)據(jù)交換下面列舉幾個常見的用法。使用POST方式請求數(shù)據(jù)使用POST方式請求數(shù)據(jù)的一般步驟如下。確定URL,一般為URI。確定請求參數(shù)。

通過URL創(chuàng)建HttpURLConnection對象。HttpURLConnection設(shè)置連接可讀寫數(shù)據(jù)。通過getOutputStream()方法獲得輸出流對象,進(jìn)而發(fā)送請求參數(shù)。13.2.4HttpURLConnection數(shù)據(jù)交換下面的代碼演示了使用POST方式請求數(shù)據(jù)的過程。publicstaticStringdoPost(Stringurl,Stringparam){PrintWriterout=null;BufferedReaderin=null;Stringresult="";try{URLrealUrl=newURL(url);//打開和URL之間的連接HttpURLConnectionconn=(HttpURLConnection)realUrl.openConnection();//設(shè)置通用的請求屬性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請求必須設(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對象對應(yīng)的輸出流out=newPrintWriter(conn.getOutputStream());//發(fā)送請求參數(shù)out.print(param);//flush輸出流的緩沖out.flush();}//定義BufferedReader輸入流來讀取URL的響應(yīng)in=newBufferedReader(newInputStreamReader(conn.getInputStream()));Stringline;while((line=in.readLine())!=null){result+=line;}}catch(Exceptione){e.printStackTrace();}//使用finally塊來關(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方式請求數(shù)據(jù)使用GET方式請求數(shù)據(jù)的一般步驟如下。確定URL,一般結(jié)構(gòu)為url+"?"+params。通過URL調(diào)用openConnection()方法創(chuàng)建HttpURLConnection對象。HttpURLConnection對象調(diào)用setConnectTimeout()方法設(shè)置網(wǎng)絡(luò)響應(yīng)時間,調(diào)用setRequestMethod()方法設(shè)置發(fā)送請求的方法。通過getInputStream()方法獲得輸入流,進(jìn)而獲得響應(yīng)。13.2.4HttpURLConnection數(shù)據(jù)交換下面的代碼演示了使用GET方式請求數(shù)據(jù)的過程。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ù)據(jù)至服務(wù)器(向服務(wù)器發(fā)送請求)時,如果知道上傳數(shù)據(jù)的大小,則應(yīng)顯式使用setFixedLengthStreamingMode()方法來設(shè)置上傳數(shù)據(jù)的精確值;如果不知道上傳數(shù)據(jù)的大小,則應(yīng)使用setChunkedStreamingMode()方法(通常使用默認(rèn)值0作為實際參數(shù)傳入)。如果兩個方法都未設(shè)置,則系統(tǒng)會強(qiáng)制將請求體中的所有內(nèi)容都緩存至內(nèi)存中(在通過網(wǎng)絡(luò)進(jìn)行傳輸之前),這樣會浪費堆內(nèi)存(甚至可能耗盡),并加重隱患。如果通過流輸入或輸出少量數(shù)據(jù),則需要使用帶緩沖區(qū)的流(如BufferedInputStream);大量讀取或輸出數(shù)據(jù)時,可忽略緩沖流(不使用緩沖流會增加磁盤輸入/輸出,默認(rèn)的流操作是直接進(jìn)行磁盤輸入/輸出的)。當(dāng)需要傳輸(輸入或輸出)大量數(shù)據(jù)時,使用“流”來限制內(nèi)存中的數(shù)據(jù)量,即將數(shù)據(jù)直接放在“流”中,而不是放在字節(jié)數(shù)組或字符串中(這些都存儲在內(nèi)存中)。任務(wù)13.1實現(xiàn)音樂播放器搜索網(wǎng)絡(luò)音樂【任務(wù)介紹】1.任務(wù)描述實現(xiàn)音樂播放器搜索網(wǎng)絡(luò)音樂的功能,并實現(xiàn)對搜索結(jié)果的播放。2.運行結(jié)果本任務(wù)運行結(jié)果如圖所示。13.1使用ConnectivityManager管理網(wǎng)絡(luò)13.2使用HttpURLConnection訪問網(wǎng)絡(luò)13.3JSON數(shù)據(jù)解析章目錄13.3.1JSON與XML對比所以,JSON和XML的輕/重量級的區(qū)別在于:JSON只提供整體解析方案,而這種方案只在解析較少的數(shù)據(jù)時才能達(dá)到良好的效果;XML提供對大規(guī)模數(shù)據(jù)的逐步解析方案,這種方案適用于對大量數(shù)據(jù)的處理。

解析方式XML目前設(shè)計了兩種解析方式:DOM和SAX。DOM是把一個數(shù)據(jù)交換格式XML看成一個DOM對象,需要把整個XML文件讀入內(nèi)存,這一點上JSON和XML的原理是一樣的。但是XML要考慮父節(jié)點和子節(jié)點,這一點上JSON的解析難度要小很多,因為JSON構(gòu)建于兩種結(jié)構(gòu)——鍵值對的集合、值的有序列表,可理解為數(shù)組。SAX不需要讀入整個文件就可以對解析出的內(nèi)容進(jìn)行處理,是一種逐步解析的方法。程序也可以隨時終止解析。13.3.1JSON與XML對比從主觀來看JSON更為清晰且冗余更少。JSON網(wǎng)站提供了對JSON語法的嚴(yán)格描述,只是描述較簡短。從總體來看XML比較適于標(biāo)記文檔,而JSON卻更適于進(jìn)行數(shù)據(jù)交換處理。編碼13.3.1JSON與XML對比傳輸速度JSON相對XML來說,數(shù)據(jù)的文件量小,傳遞的速度更快。XML格式代碼如下。<?xmlversion="1.0"encoding="utf-8"?><country><name>中國</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>臺灣</name><citys><city>臺北</city><city>高雄</city></citys></province><province><name>新疆</name><citys><city>烏魯木齊</city></citys></province></country>13.3.1JSON與XML對比JSON格式代碼如下。varcountry={name:"中國",provinces:[{name:"黑龍江",citys:{city:["哈爾濱","大慶"]}},{name:"廣東",citys:{city:["廣州","深圳","珠海"]}},{name:"臺灣",citys:{city:["臺北","高雄"]}},{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)。鍵值對的集合。在不同的編程語言中,它被理解為對象(Object)、記錄(Record)、結(jié)構(gòu)(Struct)、字典(Dictionary)、哈希表(HashTable)、有鍵列表(KeyedList)或者關(guān)聯(lián)數(shù)組(AssociativeArray)。值的有序列表。在大部分編程語言中,它被實現(xiàn)為數(shù)組(Array)、矢量(Vector)、列表(List)、序列(Sequence)。13.3.2JSON數(shù)據(jù)結(jié)構(gòu)JSON的常見數(shù)據(jù)形式有以下5種。對象一個對象以“{”開始,并以“}”結(jié)束,如圖13-2所示。一個對象包含一系列非排序的鍵值對,每個鍵值對之間使用逗號分隔。此處的對象相當(dāng)于Java中的Map<String,Object>,而不是Java中的Class。例如,一個Address對象包含如下鍵值對。{"city":"Beijing","street":"ChaoyangRoad","postcode":100025}13.3.2JSON數(shù)據(jù)結(jié)構(gòu)值值可以是雙引號標(biāo)注的字符串、數(shù)值、對象、數(shù)組、布爾值(true、false)或null,如圖所示。這些結(jié)構(gòu)可以嵌套。13.3.2JSON數(shù)據(jù)結(jié)構(gòu)數(shù)組數(shù)組使用[]包含所有元素,兩個元素之間用逗號分隔,如圖所示。元素可以是任意的值。例如,以下數(shù)組包含一個字符串、數(shù)值、布爾值和一個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)字符串字符串是以雙引號標(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是一個無序的鍵值對的集合,可以看作一個JSON對象,這是系統(tǒng)中有關(guān)JSON定義的基本單元。它的外在形式是一個用花括號標(biāo)注,并用冒號將名字和值分開的字符串,內(nèi)部形式就是一個對象。JSONObject提供了一系列的get、set和opt方法來訪問JSONObject實例。對JSONObject有兩個不同的取值方法。getType()optType()方法JSONObject13.3.3解析JSON下面的代碼用于創(chuàng)建一個JSONObject對象。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對象形式如下。{"phone":["12345678","87654321"], //數(shù)組"married":false, //布爾值"address":{"province":"jiangsu","country":"china"}, //JSON對象"age":100, //數(shù)值"name":"liweiyong" //字符串}13.3.3解析JSONJSONStringerJSONStringer是JSON文本構(gòu)建類,用于幫助快速和便捷地創(chuàng)建JSON文本。其最大的優(yōu)點在于可以減少因格式的錯誤而導(dǎo)致程序異常,引用這個類可以自動嚴(yán)格按照J(rèn)SON語法規(guī)則創(chuàng)建JSON文本。每個JSONStringer實體只能對應(yīng)創(chuàng)建一個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)形式是用方括號標(biāo)注,數(shù)值以逗號分隔(例如[value1,value2,value3])。下面的代碼是對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是類拋出的異常信息。以下情況下會產(chǎn)生JSONException。試圖解析或構(gòu)建一個格式錯誤的JSON文檔。使用null作為關(guān)鍵詞。使用JSON不支持的數(shù)值類型,如NaN或無窮大的值。使用不存在的鍵進(jìn)行查找。解析的類型不匹配。13.3.3解析JSONJSONStringJSONString是一個接口,以便其他類可以通過實現(xiàn)該接口的toString()方法來改變JSONObject、JSONArray等內(nèi)部toString()方法的功能,以實現(xiàn)它們自己的序列化。JSONWriterJSONWriter位于android.util包下,是一個快速將JSON文本寫入數(shù)據(jù)流的工具。每次只能輸出一個字符串。流中既包括字符串、數(shù)值、布爾值和空值,也包括作為對象、數(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包下,主要用來讀取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”窗口中的運行結(jié)果13.3.3解析JSON演示一個向中國天氣網(wǎng)發(fā)送獲取天氣信息的請求,然后解析獲取的JSON數(shù)據(jù)并顯示的示例。首先創(chuàng)建一個如下的請求連接工具類HttUtil,代碼如下。publicclassHttUtil{publicstaticHttpClienthttpClient=newDefaultHttpClient();/*@paramurl請求地址*@return服務(wù)器響應(yīng)的字符串*@throwsInterruptedException*@throwsExecutionException*/publicstaticStringgetRequest(finalStringurl)throwsInterruptedException,ExecutionException{FutureTask<String>task=newFutureTask<String>(newCallable<String>(){@OverridepublicStringcall()throwsException{HttpGetget=newHttpGet(url);

溫馨提示

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

評論

0/150

提交評論