2018android項目驅(qū)動式開發(fā)教程源碼與-第八章通過學(xué)習(xí)Android中工具類AsyncTask掌握_第1頁
2018android項目驅(qū)動式開發(fā)教程源碼與-第八章通過學(xué)習(xí)Android中工具類AsyncTask掌握_第2頁
2018android項目驅(qū)動式開發(fā)教程源碼與-第八章通過學(xué)習(xí)Android中工具類AsyncTask掌握_第3頁
2018android項目驅(qū)動式開發(fā)教程源碼與-第八章通過學(xué)習(xí)Android中工具類AsyncTask掌握_第4頁
2018android項目驅(qū)動式開發(fā)教程源碼與-第八章通過學(xué)習(xí)Android中工具類AsyncTask掌握_第5頁
已閱讀5頁,還剩78頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第8章網(wǎng)絡(luò)通信項目任務(wù):通過學(xué)習(xí)Android中的工具類——

Asyn k,掌握其在網(wǎng)絡(luò) 、界面更新等方面的應(yīng)用。通過絡(luò)通信的基本步驟,掌握Android系統(tǒng)中數(shù)據(jù)的傳遞和保存,并完成基于JSON的實時天氣預(yù)報數(shù)據(jù)實訓(xùn)。項目要求:1)掌握Android異步任務(wù)的原理 方法。2)掌握Thread+Handler+Message的更新界面的方法及編程結(jié)構(gòu)。3)掌握Asyn k更新界面的方法及編程結(jié)構(gòu)。4)掌握多線程下的網(wǎng)絡(luò)通訊和 的方式。5)掌握J(rèn)son、數(shù)據(jù)格式的解析。8.1 Http網(wǎng)絡(luò)通信隨著4G移動網(wǎng)絡(luò)的不斷普及,越來越多用程序需要利用網(wǎng)絡(luò)進(jìn)行 ,如機(jī)應(yīng)、網(wǎng)絡(luò) 、網(wǎng)絡(luò)電視都需要以網(wǎng)絡(luò)通信作為基本運行條件。對于Android系統(tǒng)來說,其在JDK基礎(chǔ)上支持完整的網(wǎng)絡(luò)通信,如基于TCP/IP的Socket通信和

HttpClient通信。8.1

Http網(wǎng)絡(luò)通信8.1.1

Android的HTTP通信目前,網(wǎng)絡(luò) 和數(shù)據(jù)的傳遞除了使用Socket外還可以使用WebService。在Android系統(tǒng)中對于通過URL向WebService發(fā)出請求,并得到數(shù)據(jù)的方式提供了3種解決方案,分別為URLConnection、HttpURLConnection和Apache

HttpClient。。

Apache

HttpClient已被廢棄,目前主要采用

HttpURLConnection獲取數(shù)據(jù)。8.1

Http網(wǎng)絡(luò)通信8.1.2

HttpURLConnection介紹HttpURLConnection類的作用是通過HTTP協(xié)議向服務(wù)器發(fā)送請求,并可以獲取服務(wù)器發(fā)回的數(shù)據(jù)。HttpURLConnection來自于JDK,它的完整名稱為

.HttpURLConnection。HttpURLConnection類,沒有公開的構(gòu)造方法,但我們可以通過.URL的openConnection方法獲取一個URLConnection的實例,而HttpURLConnection是它的子類。8.1 Http網(wǎng)絡(luò)通信HttpURLConnection的常見使用步驟如下:第一步:獲取HttpURLConnection

對象。URL

url=new

URL(“

”);HttpURLConnection

connection=(HttpURLConnection)

url.openConnection();8.1 Http網(wǎng)絡(luò)通信HttpURLConnection的常見使用步驟如下:第二步:進(jìn)行連接設(shè)置,常見的設(shè)置如下:setRequestMethod(String)

設(shè)置請求的方式:"GET"、"POST"。setDoOutput(boolean)

設(shè)置是否可以寫入數(shù)據(jù)。setConnectTimeout()設(shè)置一個指定的超時值(以毫秒為單位)。8.1 Http網(wǎng)絡(luò)通信HttpURLConnection的常見使用步驟如下:第三步:通過調(diào)用getResponseCode()方法獲取狀態(tài)碼,如果狀態(tài)碼為200,則表示連接成功。int

code

=

con.getResponseCode();if(code

==

200){…}8.1 Http網(wǎng)絡(luò)通信HttpURLConnection的常見使用步驟如下:第四步:連接成功后獲取服務(wù)器的輸入輸出流,并進(jìn)行讀寫操作InputStream

in=

connection.getInputStream();……8.2

異步的基本概念

同步執(zhí)行:是指程序按指令順序從頭到尾依次執(zhí)行,無論中間某個操作耗費多少時間,如果不執(zhí)行完,程序都不會繼續(xù)往下進(jìn)行。如果未采用異步任務(wù)處理,執(zhí)行一項操作需要等待5~10秒甚至更長的時間,那么這樣的應(yīng)用程序需要很久才能恢復(fù)正常操作,造成程序假死的現(xiàn)象。8.2

異步的基本概念用戶的操作事件。為了能在處理耗時較長的業(yè)務(wù)、而又要兼顧UI,不得不去新生產(chǎn)一個線程。異步處理消息是為了避免在主線一些耗時的操作。異步的好處:就是把一些操作,特別是耗時間的操作安排到去運行,主程序可以繼續(xù)做前臺的事情,防止卡在某一步失去響應(yīng)。8.3使用Thread+Handler+Message進(jìn)行異步操作8.3.1

Java線程(Thread)簡介

在傳統(tǒng)上的概念里,并發(fā)多任務(wù)的實現(xiàn)采用的是在操作系統(tǒng)(OS)級別運行多個進(jìn)程。

由于各個進(jìn)程擁有自己獨立的運行環(huán)境,進(jìn)程間的耦合關(guān)系差,并發(fā)粒度過于粗糙,并發(fā)實現(xiàn)也不太容易。

如果把進(jìn)程所占用的資源與進(jìn)的運行代碼相分離,那么在一個地址空間中便可運行多個指令流,由此產(chǎn)生線程概念。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作所謂線程(或稱線索),是指程序中的一個單一的順序控制流。多線程:指的是在單個程序中可以同時運行多個不同的線程,執(zhí)行不同的任務(wù)。多線程意味著一個程序的多行語句可以看上去幾乎在同一時間內(nèi)同時運行。線程運行狀況圖8.3Android使用Thread+Handler+Message進(jìn)行異步操作線程在創(chuàng)建的一刻(start函數(shù)),線程進(jìn)入就緒狀態(tài),由系統(tǒng)調(diào)度進(jìn)入運行狀態(tài)。其它線程進(jìn)入就緒等待狀態(tài),即在某一時刻處于運行狀態(tài)的線程唯一。

阻塞條件(等待硬件操作等)進(jìn)入阻塞狀態(tài),等待阻塞解除。阻塞解除會到就緒等待狀態(tài),直到被調(diào)度運行。在java中要想實現(xiàn)多線程,有兩種方法:一種是繼續(xù)Thread類,另外一種是實現(xiàn)Runable接口。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作1

publicclass

線程類名extends

Thread{2

@Override3 public

void

run(){4 //在此處進(jìn)入必要的功能代碼5

}在3~5行間加入線程運行的程序代碼。第1行繼續(xù)Thread類,“線程類名”為自定義名稱。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作實例化一個線程對象的方法:線程類名對象名

=new線程類名()MyThread

myThread

=

new

MyThread();8.3

Android使用Thread+Handler+Message進(jìn)行異步操作第二種實現(xiàn)Runable接口的方法。1

public

class

實現(xiàn)接口類名implements

Runnable{2

@Override3 public

void

run(){4 //在此處進(jìn)入必要的功能代碼5

}在3~5行間加入線程運行的程序代碼。第1行實現(xiàn)Runnable接口,“線程類名”為自定義名稱。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作實例化一個線程對象的方法:實現(xiàn)接口類名

對象名= new實現(xiàn)接口類名();Thread

線程名

=new

Thread(對象名);實現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:1、適合多個相同的程序代碼的線程去處理同一個資源2、可以避免java中的單繼承的限制3、增加程序的健壯性,代碼可以被多個線程共享,代碼和數(shù)據(jù)獨立。8.3Android使用Thread+Handler+Message進(jìn)行異步操作8.3.2

Android異步操作

Android是單線程模型,這意味著Android

UI操作并不是線程安全的并且UI操作必須在UI線

執(zhí)行,

與UI相關(guān)的東西,就不能放在子線處理,子線程不能操作UI,只能進(jìn)行數(shù)據(jù)、系統(tǒng)等其他非UI的操作。8.3Android使用Thread+Handler+Message進(jìn)行異步操作那么如何用好多線程呢?可以使用異步操作,不需要等待返回結(jié)果。例如:收藏功能,點擊完收藏按鈕后是否成功執(zhí)行完成后告訴我就行了,我不想等它,這里最好實現(xiàn)為異步的的操作,比較耗時的操作,需要放到其他線處理,等處理完成后,再通知界面刷新。8.3Android使用Thread+Handler+Message進(jìn)行異步操作8.3.3

Android中Thread+Handler+Message機(jī)制

為了實現(xiàn)Android異步操作機(jī)制,在Android下有Handler機(jī)制實現(xiàn)線程進(jìn)行復(fù)雜操作結(jié)束后通過向UI線程發(fā)送消息更新UI界面。8.3Android使用Thread+Handler+Message進(jìn)行異步操作LooperMessageMessageMessageThreadMessageMessageMessage

QueueUI線程與非UI線程消息通信方法UI

Thread(main

thread)ThreadHandlerHandlerLooperMessageMessage8.3Android使用Thread+Handler+Message進(jìn)行異步操作Handler在android里負(fù)責(zé)發(fā)送和處理消息,

通過它可以實現(xiàn)其他線程與Main線程之間的消息通訊。Looper負(fù)責(zé)管理線程的消息隊列和消息循環(huán)。

Message是線程間通訊的消息載體。兩個碼頭之間

貨物,Message充當(dāng)集裝箱的功能,里面可以存放任何你想要傳遞的消息。MessageQueue是消息隊列,先進(jìn)先出,它的作用是保存有待線程處理的消息。8.3Android使用Thread+Handler+Message進(jìn)行異步操作四者之間的關(guān)系是:在其他線 調(diào)用

Handler.sendMsg()方法(參數(shù)是Message對象),將需要Main線程處理的事件添加到Main線程的MessageQueue中,

Main線程通過MainLooper從消息隊列中取出

Handler發(fā)過來的這個消息時,會回調(diào)Handler的handlerMessage()方法。1

public

class

MyHandlerActivity

extends

Activity

{3 private

MyHandler

myHandler;8.3Android使用Thread+Handler+Message進(jìn)行異步操作45publicvoid

onCreate(Bundle

savedInstanceState){67super.onCreate(savedInstanceState);//啟動 線程8MyThread

m

=

new

MyThread();9new

Thread(m).start();10}11classMyHandler

extends

Handler

{12public

MyHandler()

{13}14public

MyHandler(Looper

L)

{15super(L);16}178.3Android使用Thread+Handler+Message進(jìn)行異步操作18@Override19public

void

handleMessage(Message

msg)

{20Log.d("MyHandler",

"handleMessage......");21super.handleMessage(msg);22//操作UI界面代碼23}24}2526classMyThread

implements

Runnable

{2728public

void

run()

{29//獲取消息隊列中的消息30Message

msg

=MyHandlerActivity.this.myHandler.obtainMessage();8.3Android使用Thread+Handler+Message進(jìn)行異步操作31323334//向消息中添加消息內(nèi)容//發(fā)送消息MyHandlerActivity.this.myHandler.sendMessage(msg);3536

}37}}8.3Android使用Thread+Handler+Message進(jìn)行異步操作代碼結(jié)構(gòu)為:Thread+Handler+Message

第1行定義了類MyHandler繼承于Handler類,類

要重寫handleMessage函數(shù)。

該函數(shù)輸入?yún)?shù)為接收到的Message,可以根據(jù)Message類中的What判斷消息的類型。

Message可攜帶數(shù)據(jù)放入Bundle中。在handleMessage函數(shù)中可操作UI界面元素。8.3Android使用Thread+Handler+Message進(jìn)行異步操作第26行定義了實現(xiàn)Runnable接口類,該類的run函數(shù)中為耗時的非UI操作。在完成操作后。

第24行向界面發(fā)送消息。該消息在MyHandler中的handleMessage函數(shù)中處理更新界面。8.3Android使用Thread+Handler+Message進(jìn)行異步操作8.3.4

使用Thread+Handler+Message異步加載網(wǎng)絡(luò)在Android應(yīng)用中,常常會遇到需要加載網(wǎng)絡(luò)的場景。如果直接在UI線

進(jìn)行加載會有等待時間不確定,甚至出現(xiàn)UI假死狀態(tài)。1、創(chuàng)建網(wǎng)絡(luò)異步加載線程1 private

AsyncLoadHandler

asynHandler

=

newAsyncLoadHandler();2 public

class

AsyncLoadPicThread

extends

Thread{3 Private

String

url

=8.3Android使用Thread+Handler+Message進(jìn)行異步操作4"http:/style/images/01.jpg";5

@Override6public

void

run(){7try

{8drawable

=

Drawable.createFromStream(new9URL(url).openStream(),"01.jpg");10 Message

message

=asynHandler.obtainMessage();11message.arg1

=

id;12message.obj

=

drawable;8.3Android使用Thread+Handler+Message進(jìn)行異步操作13asynHandler.sendMessage(message);14{1516171819

}}

catch

(MalformedURLException

e)e.printStackTrace();}

catch

(IOException

e)

{e.printStackTrace();}8.3

Android使用Thread+Handler+Message進(jìn)行異步操作第1行代碼用于實例化AsyncLoadHandler對象,為發(fā)送消息使用。第3行代碼用于定義String類型,值為 的地址。第8行和第9行代碼用于將 地址通過網(wǎng)絡(luò) 并加載到Drawable對象中,此過程完成

任務(wù)。第10行代碼用于為AsyncLoadHandler對象在消息隊列中獲取一個消息。第11行和第12行代碼為消息加入消息內(nèi)容。第13行代碼用于發(fā)送消息。第14~18行代碼用于捕獲網(wǎng)絡(luò) 異常。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作注意:通過此方法來控制異常是不合理的,因為這樣做會將網(wǎng)絡(luò)的異常交由上層進(jìn)行處理。合理的方式是在做網(wǎng)絡(luò)操作時檢查網(wǎng)絡(luò)連通等。8.3

Android使用Thread+Handler+Message進(jìn)行異步操作1

public

class2@Override3public

void

han4((ImageView)2、創(chuàng)建Handler實例AsyncLoadHandler

extends

Handler{dleMessage(Message

msg)

{AsyncLoadHandlerActivity.this.5findViewById(msg.arg1)).setImageDrawable((Drawable)6

msg.obj);7

}}8.3

Android使用Thread+Handler+Message進(jìn)行異步操作第3行,重寫Handler父類的handleMessage函數(shù)。第4~6行更新頁面的內(nèi)容,將線程的顯示到UI中的ImageView控件上。Handler中是可以操作UI控件,因此,在Handler中可以顯示的。8.3Android使用Thread+Handler+Message進(jìn)行異步操作在開發(fā)過,可能有多種類型。此時可以加入消息類型進(jìn)行區(qū)分不同消息。在發(fā)送消息前,向Message成員屬性what賦初值。將異步線程修改為以下代碼:1234public

void

run(){try

{………Message

message

=asynHandler.obtainMessage();5 message.what

=1;//消息類型8.3Android使用Thread+Handler+Message進(jìn)行異步操作在接收消息的方法中對Message類中的what屬性的值,依據(jù)what屬性值不同進(jìn)行不同的操作。12345public

void

handleMessage(Message

msg)

{if(msg.what==1){//此處為對應(yīng)處理代碼}}8.3Android使用Thread+Handler+Message進(jìn)行異步操作我們發(fā)現(xiàn)如果使用這樣的方

在修改程序時帶來不小的麻煩。所以將消息類型設(shè)置為靜態(tài)變量,保證

。1

private

final

static

int

msgType

=1;8.4

使用Asny步操作k進(jìn)行異8.4.1

Asyn

k簡介在上一節(jié)使用了Thread更新UI界面的方法,在新線

更新UI還必須要引入handler,這讓代碼看上去較臃腫并且讀者不容易理解。

為了解決這一問題,可以使用Android另一種機(jī)制—Asyn

k。8.4

Android使用Asny步操作k進(jìn)行異Asyn k的特點:任務(wù)在主線程之外運行,而回調(diào)方法是在主線

執(zhí)行,這就有效地避免了使用Handler帶來的麻煩。8.4

Android使用Asny步操作k進(jìn)行異

Asyn

k是Android框架提供的異步處理的輔助類,可以實現(xiàn)耗時操作在其他線程執(zhí)行,而處理結(jié)果在UI主線程執(zhí)行,對于開發(fā)者而言,AsyncTack

掉多線程和

Handler的概念。8.4

Android使用Asnyk進(jìn)行異步操作Asyn k中包括:有預(yù)處理的方法onPreExecute有

執(zhí)行任務(wù)的方法

nBackground(相當(dāng)于Thread中的run函數(shù)),onProgressUpdate(Progress...),在publishProgress方法被調(diào)用后,UI

thread將調(diào)用這個方法從而在界面上展示任務(wù)的進(jìn)展情況8.4

Android使用Asny步操作k進(jìn)行異例如:通過一個進(jìn)度條進(jìn)行展示。有返回結(jié)果的方法onPostExecute等等,這就不像handler中的post、sendMessage等方法,把所有的操作都寫在一個Runnable或handleMessage里。8.4

Android使用Asny

k進(jìn)行異步操作Asynk是使用java.util.concurrent框架來管理線程以及任務(wù)的執(zhí)行的,concurrent框架是一個非常成熟,高效的框架,經(jīng)過了嚴(yán)格的測試。這說明Asyn

k的設(shè)計很好的解決了線程存在的問題。Asyn k是抽象類,子類必須實現(xiàn)抽象方法

nBackground(Params...p),在此方法中實現(xiàn)任務(wù)的執(zhí)行工作,比如連接網(wǎng)絡(luò)獲取數(shù)據(jù)等。通常還應(yīng)該實現(xiàn)onPostExecute(Result

r)方法,因為應(yīng)用程序關(guān)心的結(jié)果在此方法中返回。需要注意的是Asyn k一定要在主線 創(chuàng)建實例。8.4

Android使用Asny步操作k進(jìn)行異Asynk中有三個參數(shù)泛型類型:

class

MyTask

extends

Asyn k<參數(shù)1,參數(shù)

2,參數(shù)3>{}參數(shù)1:向

任務(wù)的執(zhí)行方法傳遞參數(shù)的類型參數(shù)2:在 任務(wù)執(zhí)行過

,要求主UI線程處理中間狀態(tài),通常是一些UI處理中傳遞的參數(shù)類型參數(shù)3: 任務(wù)執(zhí)行完返回時的參數(shù)類型8.4

Android使用Asny

k進(jìn)行異步操作Asyn k的執(zhí)行分為4個步驟:

1)

onPreExecute()當(dāng)任務(wù)執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進(jìn)度框。2)在nBackground(Params...)此方法線程執(zhí)行,完成任務(wù)的主要工作,通常放入需要較長時間完成。在執(zhí)行過程中可以調(diào)用publicProgress(Progress...)來更新任務(wù)的進(jìn)度。8.4

Android使用Asny步操作k進(jìn)行異

3)

onProgressUpdate(Progress...)此方法在主線程執(zhí)行,用于顯示任務(wù)執(zhí)行的進(jìn)度。

4)

onPostExecute(Result)

此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。8.4

Android使用Asny

k進(jìn)行異步操作Asyn k的執(zhí)行的4個步驟。每個步驟對應(yīng)一個回調(diào)函數(shù),需要注意的是,這些函數(shù)不應(yīng)該由應(yīng)用程序調(diào)用,需要做的只是重寫父類的函數(shù)。在任務(wù)的執(zhí)行過

,這些函數(shù)被系統(tǒng)自動調(diào)用。8.4步操作k進(jìn)行異8.4.2Android使用AsnyAsyn

k的程序模型1

import

android.content.Context;2

import

android.os.Asyn

k;3

class

MyTask

extendsAsyn

k<String/*參數(shù)1*/,Integer/*參數(shù)2*/,String/*參數(shù)3*/>

{4public

MyTask(Context

context){5}6@Override7protected

void

onPreExecute(){8}9@Override10protected

String/*參數(shù)3*/8.4

Android使用Asny

k進(jìn)行異步操作

nBackground(String/*參數(shù)1*/...params){11

return

null;12

}13

@Override14

protected

voidonProgressUpdate(Integer/*參數(shù)2*/...values){8.4

Android使用Asny步操作k進(jìn)行異15

}16

@Override17

protected

void

onPostExecute(String/*參數(shù)3*/result){18

}19}第1、2行,導(dǎo)入應(yīng)用所需要的包。第3行,自定義MyTask類繼承Asyn

k,Asyn k是抽象類。8.4

Android使用Asny步操作k進(jìn)行異Asynk定義了三種泛型類型:參數(shù)1為啟動任務(wù)執(zhí)行的輸入?yún)?shù)在實例中定義為String類型,參數(shù)2為參數(shù)3為任務(wù)執(zhí)行的百分比,執(zhí)行任務(wù)最終返回的結(jié)果。

第4、5行為MyTask的構(gòu)造函數(shù),定義輸入?yún)?shù)為上下文Context。此構(gòu)造函數(shù)不是必須的。

第7、8行是在 執(zhí)行前調(diào)用的函數(shù),一般作為

的準(zhǔn)備。如啟動一個

框等。8.4

Android使用Asny步操作k進(jìn)行異

第10、11行為 執(zhí)行的部分,輸入?yún)?shù)是Asyn

k泛型參數(shù)1的類型。常用來傳遞行為參數(shù)等。返回值為Asyn k泛型參數(shù)3的類型,值為onPostExecute函數(shù)使用。

第14、15行當(dāng)在

nBackground

調(diào)用publishProgress后,系統(tǒng)會調(diào)用用戶定義的onProgressUpdate函數(shù),并將publishProgress的參數(shù)傳入onProgressUpdate。第17、18行是的

nBackground結(jié)束后調(diào)用的UI前臺函數(shù)。并將

nBackground的返回值傳入。8.4

Android使用Asny步操作k進(jìn)行異注意:Asynk不能完全取代線程,在一些邏輯較為復(fù)雜或者需要在

反復(fù)執(zhí)行的邏輯就可能需要線程來實現(xiàn)了8.4Android使用Asnyk進(jìn)行異步操作8.4.3使用Asyn k異步加載網(wǎng)絡(luò)創(chuàng)建網(wǎng)絡(luò)異步加載任1

class

AsyncLoadTask

extends

Asyn k<String,

Integer,

Bitmap>

{2@Override3

protected

Bitmap nBackground(String...

params)

{4Bitmap

bitmap

=

downloadImage();5return

bitmap;6}7@Override8protected

void

onPostExecute(Bitmap

bitmap){9if(result

!=

null)

{10mImage.setImageBitmap(bitmap);11}else8.4 Android使用Asny步操作k進(jìn)行異12mImage.setBackgroundResource(R.drawable.icon);super.onPostExecute(bitmap);1314mProcessDialog.setVisibility(View.GONE);15}16@Override17protected

void

onProgressUpdate(Integer...

values){18mProcessDialog.setProgress(values[0]);19super.onProgressUpdate(values);20}21@Override22protected

void

onPreExecute()

{2324mProcessDialog.setVisibility(View.VISIBLE);mProcessDialog.setProgress(0);super.onPreExecute();2526}27}8.4 Android使用Asny步操作k進(jìn)行異

第4行代碼中的完成網(wǎng)絡(luò)nBackground()函數(shù)是在功能。onPostExecute()和onPreExecute()函數(shù)分別是 線程運行前后的前臺處理函數(shù)。

第17行代碼用于在

nBackground()函數(shù)中啟動onProgressUpdate()函數(shù)更新

。8.5

JSON的基本概念和用法8.5.1

JSON的基本概念JSON(JavaScript

Object

Notation)

是一種輕量級的

格式,采用完全獨立言的文本格式,是理想的

格式。同時,JSON是

JavaScript

原生格式,這意味著在

JavaScript

中處理

JSON數(shù)據(jù)不須要任何特殊的

API

或工具包。8.5

JSON的基本概念和用法在JSON中,有兩種結(jié)構(gòu):對象和數(shù)組。對象結(jié)構(gòu)以“{”大括號開始,以“}”大括號結(jié)束。中間部分由0或多個以“,”分隔的“key(關(guān)鍵字)/value(值)”對構(gòu)成,關(guān)鍵字和值之間以“:”分隔,語法結(jié)構(gòu)如代碼所述:{

" Name":

"Brett","lastName":"McLaughlin",

" ":

"aaaa"

}8.5

JSON的基本概念和用法數(shù)組結(jié)構(gòu)以“[”開始,“]”結(jié)束。中間由0或多個以“,”分隔的值列表組成,語法結(jié)構(gòu)如代碼所述:{

"people":

[{

" Name":

"Brett",

"lastName":"McLaughlin"," ":

"aaaa"

},{

" Name":

"Jason",

"lastName":"Hunter"," ":

"bbbb"},{

" Name":

"Elliotte",

"lastName":"Harold"," ":

"cccc"

}]}8.5

JSON的基本概念和用法8.5.2

JSON解析解析JSON數(shù)據(jù)有多種方法,主要包括以下兩種形式:使用使用第自帶JSONObject、JSONArray。開源庫,包括但不限于GSON、FastJSON、Jackson等。8.5

JSON的基本概念和用法JSONObject可以看作是一個JSON對象,這是系統(tǒng)中有關(guān)

JSON定義的基本單元,其包含一對數(shù)值(Key/Value)。通過調(diào)用JSONObject的各種getXXX(String

name)方法,傳入?yún)?shù)鍵值name,就可以獲得JSON對象的value值。String

s1

=

{" Name":

"Brett",

"lastName":"McLaughlin"," ":

"aaaa"

}JSONObject

jsonObject

=

new

JSONObject(s1);String Name

=jsonObject.getString("

Name");String

lastName

=

jsonObject.getString("lastName");String =

jsonObject.getString("

");8.5

JSON的基本概念和用法JSONArray可以看作是一個JSON數(shù)組,它代表一組有序的數(shù)值。使用方法類似數(shù)組,循環(huán)遍歷JSONArray,通過調(diào)用getJSONObject(int

index)方法,獲得指定索引的JSON對象JSONObject。(見

《JSON》)String

s2

=

{"people":

[":":":

"cccc"{

" Name":

"Brett",

"lastName":"McLaughlin",

""aaaa"

},{

" Name":

"Jason",

"lastName":"Hunter",

""bbbb"},{

" Name":

"Elliotte",

"lastName":"Harold",

"}]}8.5

JSON的基本概念和用法JSONObject

jsonObject

=

new

JSONObject(s2);JSONArray

jsonArray

=jsonObject.getJSONArray("people");for

(int

i=

0;

i<

jsonArray.length();i++){JSONObject

jsonObject2

=

jsonArray.getJSONObject(i);String Name2

=jsonObject2.getString("

Name");String

lastName2

=jsonObject2.getString("lastName");String 2

=

jsonObject2.getString("

");}8.5

JSON的基本概念和用法Gson是進(jìn)行提供的用來在Java對象和JSON數(shù)據(jù)之間的Java類庫,可以將一個JSON字符串轉(zhuǎn)成一個Java對象,或者反過來。通過調(diào)用toJson(XXX)方法把

Java對象轉(zhuǎn)換為JSON字符串,或者通過調(diào)用

fromJson(XXX)方法把JSON字符串轉(zhuǎn)換為Java對象。使用Gson解析之前,需要先把Gson開源庫添加到項目中,這里介紹兩種添加方法。①

在build.gradle中找到dependencies模塊,輸入compile

'com.

.code.gson:gson:2.6.2'通過這種方式,必須知道第

開源庫的名稱和版本號。②

可視化界面添加Gson開源庫8.5

JSON的基本概念和用法可視化界面添加Gson開源庫8.5

JSON的基本概念和用法通過Gson開源庫把Java對象轉(zhuǎn)換為JSON對象,或者把JSON對象轉(zhuǎn)換為Java對象都非常簡單。Gson

gson

=

new

Gson();=

newString

s1

=

gson.toJson(("a",18););2

=gson.fromJson(s1,.class);8.5

JSON的基本概念和用法把集合轉(zhuǎn)換為JSON數(shù)組直接調(diào)用Gson的toJson(XXX)方法即可,把JSON數(shù)組轉(zhuǎn)換為集合依然調(diào)用Gson的fromJson方法,但是參數(shù)中需要一個Type類型,表示轉(zhuǎn)換后的集合類型。Type

type

=

new

TypeToken<List<

>>(){}.getType();List<

> s

=gson.fromJson(s2,type);textView2.setText(s2

+

"\n"+

s.toString());8.6

實訓(xùn)項目與演練8.6.1實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)從圖中可以看出,該界面分為3個部分,并且是垂直線性布局,在布局的最上部為當(dāng)前的數(shù)據(jù)日期,中部為天氣的詳細(xì)信息,下部為一些天氣指數(shù)信息。8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)本例中的代碼一共分為四個功能模塊,模塊說明如下:載入模塊:載入所有資源文件中的天氣類型1)天氣。2)網(wǎng)絡(luò)數(shù)據(jù)出請求,并模塊:通過HTTP

GET向中國氣象網(wǎng)發(fā)返回的天氣數(shù)據(jù)。3)JSON數(shù)據(jù)解析模塊:該模塊通過解析網(wǎng)絡(luò)數(shù)據(jù)模塊中獲取的數(shù)據(jù),從而得到城市的實時天氣狀況和各類指數(shù)。4)界面數(shù)據(jù)匹配模塊:把從JSON數(shù)據(jù)解析模塊中得到的數(shù)據(jù)與界面組件相匹配,從而讓界面顯示正確的天氣信息。8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)天氣 載入模塊的代碼如下://載入天氣圖標(biāo)和對應(yīng)的說明2private

Map<String,

Integer>

loadWeaterIcon()

{3//

TODO

Auto-generated

method

stub4String[]

weatherDes

=5{6"薄霧","濃霧","雷電","雷陣雨",7"雷電有雪","雷暴","小雨","中雨",8"小雪","大雨","大雪","晴轉(zhuǎn)多云",9"多云轉(zhuǎn)晴","晴轉(zhuǎn)陰","多云","晴"10};11Integer[]

weatherID

=128.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn){13R.drawable.weather_01,

R.drawable.weather_02,14R.drawable.weather_03,

R.drawable.weather_04,15R.drawable.weather_05,

R.drawable.weather_06,16R.drawable.weather_07,

R.drawable.weather_08,17R.drawable.weather_09,

R.drawable.weather_10,18R.drawable.weather_11,R.drawable.weather_12,19R.drawable.weather_13,

R.drawable.weather_14,20R.drawable.weather_15,

R.drawable.weather_1621};22Map<String,

Integer>

weatherICON

=

newHashMap<String,

Integer>();23 for

(int

i

=0;

i<

weatherID.length;

i++)

{24weatherICON.put(weatherDes[i],

weatherID[i]);25}2627returnweatherICON;28}8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)網(wǎng)絡(luò)數(shù)據(jù) 模塊的代碼如下:public

void

run()

{2//TODO

Auto-generated

methodstub3//保存服務(wù)器返回數(shù)據(jù)4StringBuffer

response

=

new

StringBuffer();5HttpClient

httpClient

=

new

DefaultHttpClient();6//創(chuàng)建HttpGet對象7HttpGet

httpGet

=

newHttpGet(url);8//發(fā)送Http請求9try{10 HttpResponse

httpResponse=httpClient.execute(httpGet);8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)11121314BufferedReader(15HttpEntity

httpEntity

=

httpResponse.getEntity();if

(httpEntity!=

null)

{//服務(wù)器響應(yīng)BufferedReader

bReader

=newnewInputStreamReader(httpEntity.getContent()));String

line

=

"";while

((line

=

bReader.readLine())!=1617null)

{18192021面2223//在文本框中顯示response.append(line

+

"\n");}//

把從服務(wù)器中獲取的天氣

到主界Message

msg

=

new

Message();msg.what

=

0x01;8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)Bundle

bundle

=

new

Bundle();bundle.putString("weather",msg.setData(bundle);handler.sendMessage(msg);}}

catch

(ClientProtocolException

e)

{//

TODO

Auto-generated

catch

blocke.printStackTrace();}catch

(IOException

e){//

TODO

Auto-generated

catch

blocke.printStackTrace();}2425response.toString());2627282930313233343536

}8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)JSON數(shù)據(jù)解析模塊的代碼如下:1//解析服務(wù)器傳遞會來的數(shù)據(jù)2priva ist<String>

parseJSON(String

jsonData)

{3//TODO

Auto-generated

methodstub4List<String>

datasList

=

new

ArrayList<String>();56try

{7//產(chǎn)生一個JSONObject對象8JSONObject

jsonObject

=

new

JSONObject(jsonData).9getJSONObject("weatherinfo");1011datasList.add(jsonObject.getString("date_y")12+jsonObject.getString("week"));13datasList.add(jsonObject.getString("date"));8.6

實訓(xùn)一:實時天氣預(yù)報的實現(xiàn)141516datasList.add(jsonObject.getString("city"));datasList.add(jsonObject.getString("temp1"));datasList.add(jsonObject.getString("weather1"));datasList.add(jsonObject.getString("wind1"));datasList.add(jsonObjec

溫馨提示

  • 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

提交評論