android項(xiàng)目課程的設(shè)計(jì)與實(shí)施國培thread_第1頁
android項(xiàng)目課程的設(shè)計(jì)與實(shí)施國培thread_第2頁
android項(xiàng)目課程的設(shè)計(jì)與實(shí)施國培thread_第3頁
android項(xiàng)目課程的設(shè)計(jì)與實(shí)施國培thread_第4頁
android項(xiàng)目課程的設(shè)計(jì)與實(shí)施國培thread_第5頁
已閱讀5頁,還剩55頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

Android項(xiàng)目課程的設(shè)計(jì)與實(shí)施(國培)第8天Android線程機(jī)制項(xiàng)目涉及技能#技能項(xiàng)重點(diǎn)難點(diǎn)隸屬課程1Activity組件√Android程序設(shè)計(jì)基礎(chǔ)2Boradcastreceiver組件√√Android程序設(shè)計(jì)基礎(chǔ)3線程√√Android程序設(shè)計(jì)基礎(chǔ)4Service組件√Android程序設(shè)計(jì)基礎(chǔ)5自定義組件(button)√√Android高級(jí)程序設(shè)計(jì)6文件讀寫與數(shù)據(jù)存儲(chǔ)√Android高級(jí)程序設(shè)計(jì)主要內(nèi)容認(rèn)識(shí)線程線程的基本用法線程間通信機(jī)制AsyncTask子線程更新UI線程同步認(rèn)識(shí)線程Android是單線程模型,我們創(chuàng)建的Service、Activity以及Broadcast均是在一個(gè)主線程處理,這里我們可以理解為UI線程。

但是在操作一些耗時(shí)操作時(shí),比如I/O讀寫的大文件讀寫,數(shù)據(jù)庫操作以及網(wǎng)絡(luò)下載需要很長時(shí)間,為了不阻塞用戶界面,出現(xiàn)ANR的響應(yīng)提示窗口,這個(gè)時(shí)候我們考慮使用Thread線程來解決。認(rèn)識(shí)線程進(jìn)程與線程線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體,與進(jìn)程的區(qū)別:

(1)地址空間:進(jìn)程內(nèi)的一個(gè)執(zhí)行單元;進(jìn)程至少有一個(gè)線程,它們共享進(jìn)程的地址空間;而進(jìn)程有自己獨(dú)立的地址空間;

(2)資源擁有:進(jìn)程是資源分配和擁有的單位,同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程的資源

(3)線程是處理器調(diào)度的基本單位,但進(jìn)程不是.

(4)二者均可并發(fā)執(zhí)行.

基本用法實(shí)現(xiàn)繼承java.lang.Thread類

實(shí)現(xiàn)Runnable接口啟動(dòng)Thread類代表線程類,它的兩個(gè)最主要的方法是:

run()——包含線程運(yùn)行時(shí)所執(zhí)行的代碼

Start()——用于啟動(dòng)線程通信Handler機(jī)制,它是Runnable和Activity交互的橋梁,在run方法中發(fā)送Message,在Handler里,通過不同的Message執(zhí)行不同的任務(wù)。線程同步簡(jiǎn)介當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),非常容易出現(xiàn)線程安全問題(比如多個(gè)線程都在操作同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致),所以我們用同步機(jī)制來解決這些問題。實(shí)現(xiàn)方法同步代碼塊:

synchronized(同一個(gè)數(shù)據(jù)){}

同一個(gè)數(shù)據(jù):就是N條線程同時(shí)訪問一個(gè)數(shù)據(jù)。同步方法:

publicsynchronized

數(shù)據(jù)返回類型

方法名(){}子線程更新UI子線程更新UI的四種方法handle.post(Runnabler)handle.handleMessage(Messagemsg)runOnUiThread(Runnabler)View.post(Runnabler)線程間通訊

Handler

:在android里負(fù)責(zé)發(fā)送和處理消息,通過它可以實(shí)現(xiàn)其他線程與Main線程之間的消息通訊。

Looper:負(fù)責(zé)管理線程的消息隊(duì)列和消息循環(huán)

。Message

:線程間通訊的消息載體。兩個(gè)碼頭之間運(yùn)輸貨物,Message充當(dāng)集裝箱的功能,里面可以存放任何你想要傳遞的消息。

MessageQueue:消息隊(duì)列,先進(jìn)先出,它的作用是保存有待線程處理的消息。

用于線程間通訊的類Android多線程機(jī)制

Android多線程3.1使用線程任何耗時(shí)的處理過程都會(huì)降低用戶界面的響應(yīng)速度,甚至導(dǎo)致用戶界面失去響應(yīng),當(dāng)用戶界面失去響應(yīng)超過5秒鐘,Android系統(tǒng)會(huì)允許用戶強(qiáng)行關(guān)閉應(yīng)用程序較好的解決方法是將耗時(shí)的處理過程轉(zhuǎn)移到子線程上,這樣可以避免負(fù)責(zé)界面更新的主線程無法處理界面事件,從而避免用戶界面長時(shí)間失去響應(yīng)本地服務(wù)3.1使用線程線程是獨(dú)立的程序單元,多個(gè)線程可以并行工作在多處理器系統(tǒng)中,每個(gè)中央處理器(CPU)單獨(dú)運(yùn)行一個(gè)線程,因此線程是并行工作的在單處理器系統(tǒng)中,處理器會(huì)給每個(gè)線程一小段時(shí)間,在這個(gè)時(shí)間內(nèi)線程是被執(zhí)行的,然后處理器執(zhí)行下一個(gè)線程,這樣就產(chǎn)生了線程并行運(yùn)行的假象無論線程是否真的并行工作,在宏觀上可以認(rèn)為子線程是獨(dú)立于主線程,且能與主線程并行工作的程序單元3本地服務(wù)3.1使用線程Android中的線程是基于Java定義的線程,其內(nèi)部結(jié)構(gòu)如圖所示:…消息隊(duì)列消息隊(duì)列線程1run(){…}線程N(yùn)run(){…}3本地服務(wù)3.1使用線程一個(gè)應(yīng)用程序中可能會(huì)包含多個(gè)線程(Thread),每個(gè)線程中都有一個(gè)run()方法,run()方法內(nèi)部的程序執(zhí)行完畢后,所在的線程就自動(dòng)結(jié)束。每個(gè)線程都有一個(gè)消息隊(duì)列,用于不同的線程之間傳遞消息。在run()方法內(nèi)部,如果不主動(dòng)去讀取消息隊(duì)列中的消息,這些消息就是一些無用的消息,因?yàn)樗鼈儧]有被處理。3本地服務(wù)3.1使用線程在Android系統(tǒng)中,讀取消息和處理消息是兩個(gè)步驟,并由兩個(gè)不同的部分完成,先讀取消息,然后才能處理消息。無論是本線程的還是其它線程,都不能直接處理消息隊(duì)列中的消息,而是需要通過在線程內(nèi)部定義一個(gè)Handler類對(duì)象來處理消息隊(duì)列。一個(gè)Thread只能包含一個(gè)Handler對(duì)象。在實(shí)際應(yīng)用中,讀取消息隊(duì)列一般需要循環(huán)執(zhí)行,即不斷地從消息隊(duì)列中獲取消息并進(jìn)行相應(yīng)處理,這就又需要一個(gè)Looper對(duì)象。3本地服務(wù)3.1使用線程Looper對(duì)象用于循環(huán)讀取消息隊(duì)列的值,并回調(diào)Handler對(duì)象中定義的消息處理函數(shù),同時(shí),Looper對(duì)象還可以將讀取的消息從隊(duì)列中移除,執(zhí)行完一次消息處理后,再循環(huán)從消息隊(duì)列中讀取下一個(gè)消息,直到Looper對(duì)象調(diào)用stop()方法退出循環(huán)。如果消息隊(duì)列中沒有消息,Looper對(duì)象則會(huì)等待,線程不會(huì)退出。為了更方便地從線程中使用Looper功能,Android又定義了一個(gè)HandlerThread類,該類基于Thread,并且內(nèi)部已經(jīng)添加了Looper功能,使用者只需重寫其onLooperPrepared()方法,添加具體應(yīng)用代碼即可。Android中一個(gè)Activity就是一個(gè)線程,多個(gè)Activity之間的切換是在同一個(gè)線程中。Android中Activity的調(diào)用流程publicclassPseudoActivityextendsThread{ voidrun(){ while(1){ //如果定義了Handler對(duì)象,則進(jìn)行消息派發(fā)

if(hasHandler()){ if(MessageQueue.getMessage()!=null) Handler.handleMessage(); //執(zhí)行完一個(gè)消息后,接著執(zhí)行與用戶界面相關(guān)的響應(yīng)。

activity(){ //以下是Activity的核心代碼,包括用戶按鍵消息、菜單、對(duì)話框等處理。 //經(jīng)過ifelse等程序控制語句,回調(diào)一些接口函數(shù),如onXXX()。 if..else.. switch...case...for...onCreate...,,,onStart(); }}}} //以下為一些回調(diào)函數(shù)定義

publicvoidonCreate(){ } publiconStart(){ } ....}

3本地服務(wù)3.1使用線程以上偽代碼中,while(1)循環(huán)用于指定該Thread一直執(zhí)行,永不退出,直到被操作系統(tǒng)殺掉。if(hasHandler())語句判斷該Thread中是否定義了Handler對(duì)象,該Handler對(duì)象是由應(yīng)用程序定義的(也可不定義);如果有該對(duì)象,那么就會(huì)讀取Thread中消息隊(duì)列的值,并做一定的處理。執(zhí)行完一個(gè)消息后,接著需要執(zhí)行Activity中的用戶界面響應(yīng),例如是否有按鍵按下、觸摸屏是否按下等。處理完一次用戶消息響應(yīng)后,則繼續(xù)循環(huán)讀取Thread中消息隊(duì)列的值。MessageQueue、Looper、Handler調(diào)用關(guān)系在以上這個(gè)大循環(huán)中,Handler對(duì)象對(duì)應(yīng)的就是Handler.handleMessage()部分完成的功能,Looper對(duì)象對(duì)應(yīng)的就是整個(gè)while(1)循環(huán)控制和MessageQueue.getMessage()完成的功能。一個(gè)ThreadHandler接口對(duì)象Looper對(duì)象MessageQueue(消息隊(duì)列)其它功能函數(shù)3本地服務(wù)3.1使用線程Looper對(duì)象負(fù)責(zé)從線程的消息隊(duì)列中循環(huán)讀取消息值,再將這些消息傳遞給Handler對(duì)象,Handler對(duì)象中定義的消息處理函數(shù)會(huì)根據(jù)消息類型再調(diào)用Thread中定義的其它函數(shù)。如果Thread中沒有Looper對(duì)象,那么Thread的執(zhí)行體就無法讀取消息隊(duì)列;如果Thread中沒有Handler對(duì)象,則不會(huì)處理任何消息。一般情況下,Handler和Looper是同時(shí)使用的,要么同時(shí)有,要么同時(shí)沒有。Android多線程定義

4線程定義4.1線程定義Android中定義線程的方法與Java相同,可以使用兩種方法:一種是Thread類,另一種是Runnable接口。Thread是一個(gè)類,根據(jù)Java繼承風(fēng)格,一個(gè)類只能有一個(gè)父類,繼承了Thread的子類不能再繼承其它類,這是一個(gè)缺陷。于是,出現(xiàn)了Runnable,其作用和Thread相同,都是啟動(dòng)另一個(gè)線程,不同的是,Runnable是一個(gè)接口(interface),因此可以同時(shí)實(shí)現(xiàn)多個(gè)接口。4線程定義4.1線程定義Android中使用Thread與Java基本相同,所不同的是,Android拋棄了Java線程中一些不安全的做法。比如:終止一個(gè)Thread,在Java中可以調(diào)用線程名字.stop()、線程名字.destroy()等;而在Android中,這些方法都沒有實(shí)現(xiàn),即不能使用。新建一個(gè)Thread對(duì)象,需要實(shí)現(xiàn)兩個(gè)方法:4線程定義4.1線程定義第一個(gè)是定義構(gòu)造方法。在Android程序中,新建的線程多為Activity、Service等程序片斷服務(wù),而在線程的內(nèi)部執(zhí)行過程中,很多時(shí)候都需要使用應(yīng)用程序內(nèi)部的Context對(duì)象,因此,在實(shí)際應(yīng)用中,線程的構(gòu)造方法往往會(huì)傳遞應(yīng)用程序的Context對(duì)象,從而在線程的內(nèi)部可以調(diào)用Context相關(guān)的系統(tǒng)服務(wù)。當(dāng)然,這不是必須的。第二個(gè)是run()方法,該方法是Thread對(duì)象中必須實(shí)現(xiàn)的方法,用于完成具體的任務(wù)。啟動(dòng)線程時(shí),不能直接調(diào)用線程名字.run()方法,而是調(diào)用線程名字.start()方法啟動(dòng),start()方法是Thread內(nèi)部使用的,該方法包含初始化線程的工作,然后回調(diào)run()方法,這些對(duì)應(yīng)用程序都是不可見的。4線程定義4.1線程定義停止線程時(shí),不能調(diào)用線程名字.destroy()方法或者線程名字.stop()方法。run()方法執(zhí)行完畢后,線程默認(rèn)會(huì)自動(dòng)停止。因此,如果需要線程循環(huán)執(zhí)行run()方法內(nèi)部的代碼,可以在線程內(nèi)部增加一個(gè)狀態(tài)變量,run()方法內(nèi)部通過檢查該狀態(tài)變量,決定是否繼續(xù)執(zhí)行;同時(shí)可在線程外設(shè)置該狀態(tài)變量的值,從而終止該線程。4線程定義4.1線程定義線程定義Thread繼承Thread類,并重寫run()方法。在run()中放置代碼的主體部分classThread1extendsThread{privateContextmCtx; Thread1(Contextcontext){ mCtx=context; }@Override publicvoidrun(){

//過程代碼}4線程定義4.1線程定義以上代碼包括3個(gè)基本方法:Thread1()為構(gòu)造方法,用于保存調(diào)用者的Context對(duì)象,供以后可能使用;run()方法內(nèi)部是應(yīng)用代碼;setToStop()用于設(shè)置全局變量mRunState的值,run()內(nèi)部循環(huán)執(zhí)行時(shí)會(huì)判斷該值,決定是否退出run()方法,即終止該線程。要在Activity啟動(dòng)Thread1,首先需要定義一個(gè)Thread1對(duì)象,并使用構(gòu)造方法將Activity的Context對(duì)象傳遞給Thread1,然后調(diào)用線程的start()方法啟動(dòng)Thread1線程。要終止Thread的運(yùn)行,可調(diào)用自定義的Thread1的setToStop()方法。以上代碼中,id值為action_stop的按鈕,用于停止Thread1的運(yùn)行。這是Android系統(tǒng)建議的啟動(dòng)線程和退出線程的方法。4線程定義4.1線程定義RunnableRunnable的作用和Thread基本相同,都是用于定義一個(gè)線程,但兩者本質(zhì)上有重要區(qū)別。第1:Runnable只是一個(gè)接口(interface),其內(nèi)部沒有定義任何已實(shí)現(xiàn)的方法。因此,要使用與線程有關(guān)的方法,只能使用Thread的靜態(tài)方法,比如:不能直接調(diào)用sleep(),而要調(diào)用Thread.sleep()方法。4線程定義4.1線程定義Runnable第2:定義一個(gè)Thread對(duì)象,就意味著創(chuàng)建了一個(gè)新線程,而定義一個(gè)Runnable對(duì)象,只是定義了一個(gè)可以當(dāng)作線程運(yùn)行的代碼對(duì)象,并沒有創(chuàng)建新線程。因此,如果調(diào)用Runnable對(duì)象的run()方法,僅相當(dāng)于把Runnable對(duì)象當(dāng)作普通類對(duì)象進(jìn)行調(diào)用,并沒有啟動(dòng)一個(gè)新線程,Runnable對(duì)象和調(diào)用者在同一個(gè)線程中運(yùn)行。如果要?jiǎng)?chuàng)建一個(gè)新線程,則還需要將Runnable對(duì)象傳入Thread的構(gòu)造方法,從而創(chuàng)建一個(gè)新線程,新線程的執(zhí)行碼就是Runnable所定義的。4線程定義4.1線程定義Runnable第3:Runnable對(duì)象經(jīng)常被當(dāng)作參數(shù)傳遞給一些與線程有關(guān)的方法,用于啟動(dòng)一個(gè)新的線程。4線程定義4.1線程定義線程定義Runnable實(shí)現(xiàn)Java的Runnable接口,并重載run()方法。在run()中放置代碼的主體部分privateRunnablebackgroudWork=newRunnable(){ @Override publicvoidrun(){ //過程代碼 } };4線程定義4.1線程定義線程定義實(shí)現(xiàn)Java的Runnable接口,并重載run()方法。在run()中放置代碼的主體部分。privateRunnablebackgroudWork=newRunnable(){ @Override publicvoidrun(){ //過程代碼 } };4線程定義4.1線程定義線程定義創(chuàng)建Thread對(duì)象,并將上面實(shí)現(xiàn)的Runnable對(duì)象作為參數(shù)傳遞給Thread對(duì)象Thread的構(gòu)造函數(shù)中,第1個(gè)參數(shù)用來表示線程組第2個(gè)參數(shù)是需要執(zhí)行的Runnable對(duì)象第3個(gè)參數(shù)是線程的名稱調(diào)用start()方法啟動(dòng)線程privateThreadworkThread;workThread=newThread(null,backgroudWork,"WorkThread");workThread.start();4線程定義4.1線程定義線程在run()方法返回后,線程就自動(dòng)終止了;不推薦使用調(diào)用stop()方法在外部終止線程最好的方法是通知線程自行終止,一般調(diào)用interrupt()方法通告線程準(zhǔn)備終止,線程會(huì)釋放它正在使用的資源,在完成所有的清理工作后自行關(guān)閉interrupt()方法并不能直接終止線程,僅是改變了線程內(nèi)部的一個(gè)布爾字段,run()方法能夠檢測(cè)到這個(gè)布爾字段,從而知道何時(shí)應(yīng)該釋放資源和終止線程在run()方法的代碼,一般通過Terrupted()方法查詢線程是否被中斷workTerrupt();4線程定義4.1線程定義下面的代碼是以1秒為間隔循環(huán)檢測(cè)斷線程是否被中斷第4行代碼使線程休眠1000毫秒當(dāng)線程在休眠過程中被中斷,則會(huì)產(chǎn)生InterruptedException在中斷的線程上調(diào)用sleep()方法,同樣會(huì)產(chǎn)生InterruptedExceptionpublicvoidrun(){ while(!Terrupted()){ //過程代碼 Thread.sleep(1000); }}4線程定義4.1線程定義Terrupted()方法功能判斷線程是否應(yīng)被中斷通過捕獲InterruptedException判斷線程是否應(yīng)被中斷,并且在捕獲到InterruptedException后,安全終止線程publicvoidrun(){ try{ while(true){ //過程代碼 Thread.sleep(1000); } }catch(InterruptedExceptione){ e.printStackTrace(); }}Handler5

Handler5.1使用HandlerHandler用于處理線程中的消息隊(duì)列。當(dāng)Looper對(duì)象從消息隊(duì)列中獲取消息后,會(huì)把消息派發(fā)給Handler對(duì)象。一個(gè)線程中只能有一個(gè)Handler對(duì)象,可以通過該對(duì)象向所在線程發(fā)送消息。因此,只要擁有其它線程中Handler對(duì)象的引用,就可以向其發(fā)送消息;除了給別的線程發(fā)送消息外,還可以給本線程發(fā)送消息。5

Handler5.1使用HandlerHandler一般有兩種用途:實(shí)現(xiàn)一個(gè)定時(shí)任務(wù)。這個(gè)有點(diǎn)類似于Windows中的定時(shí)器功能,可以通過Handler對(duì)象向所在線程發(fā)送一個(gè)延時(shí)消息。當(dāng)消息指定的時(shí)間到達(dá)后,通過Handler對(duì)象的消息處理方法完成指定任務(wù)。在線程間傳遞數(shù)據(jù)。5

Handler5.1使用HandlerHandler完成定時(shí)任務(wù)在一個(gè)Activity內(nèi)部,經(jīng)常需要做一些定時(shí)器的功能,比如周期性更新某個(gè)視圖的內(nèi)容、在指定時(shí)間后結(jié)束某個(gè)操作等。完成定時(shí)任務(wù),可以通過Handler對(duì)象的延遲發(fā)送消息方法來實(shí)現(xiàn)。在介紹發(fā)送消息之前,需要先了解一下消息Message的數(shù)據(jù)結(jié)構(gòu)。Message是一個(gè)描述消息的數(shù)據(jù)結(jié)構(gòu)類,Message包含很多成員變量和方法,但對(duì)于簡(jiǎn)單的消息處理,一般僅需了解3項(xiàng),分別是:intwhat這是用戶自定義的一個(gè)整型值,用于區(qū)分消息類型。intarg1這是額外消息參數(shù)intarg2同arg1對(duì)于需要包含更多數(shù)據(jù)的消息,可以使用message.setData()和getData()方法。setData()方法用于把一個(gè)Bundle類數(shù)據(jù)對(duì)象加入到Message中,而getData()則是取出該Bundle數(shù)據(jù)。Bundle數(shù)據(jù)類型就是包含“鍵值對(duì)”數(shù)據(jù)的類型。Handler發(fā)送消息的方式:一類是postXXX()方法,該方法用于把一個(gè)Runnable對(duì)象發(fā)送到消息隊(duì)列。從而當(dāng)消息被處理時(shí),能夠執(zhí)行Runnable對(duì)象;另一類是sendXXX()方法,該方法用于發(fā)送一個(gè)Message類型的消息到消息隊(duì)列,當(dāng)消息被處理時(shí),系統(tǒng)會(huì)調(diào)用Handler對(duì)象定義的handleMessage()方法處理該消息。實(shí)現(xiàn)定時(shí)任務(wù)則主要使用sendXXX()類,該類具體包含如下方法:sendEmptyMessage(intwhat),空消息是指該消息僅包含what值。sendEmptyMessageAtTime(intwhat,longuptimeMilis),在指定時(shí)間點(diǎn)發(fā)送空消息,uptimeMilis是指從本次開機(jī)開始運(yùn)行的時(shí)間點(diǎn),不包含系統(tǒng)休眠的時(shí)間,單位為毫秒。參照SystemClock類。sendEmptyMessageDelayed(intwhat,longdelayMillis),在指定時(shí)間后發(fā)送空消息,指定的時(shí)間以毫秒為單位。sendMessage(Message),發(fā)送Message指定的消息。sendMessageAtTime(Message,long),在指定時(shí)間點(diǎn)發(fā)送該消息。sendMessageDelayed(Message,long),在指定的時(shí)間后發(fā)送該消息。實(shí)現(xiàn)定時(shí)任務(wù)時(shí),一般使用sendMessageAtDelayed()或者sendEmptyMessageAtDelayed()方法,即在指定的時(shí)間后發(fā)送消息。當(dāng)收到該消息后,系統(tǒng)會(huì)調(diào)用Handler對(duì)象實(shí)現(xiàn)的消息處理接口handlhandleMessage()的參數(shù)是Message對(duì)象,可以通過Message的相關(guān)方法獲得Message的具體值,并根據(jù)其消息完成不同的任務(wù)。Handle定時(shí)任務(wù)案例演示1)、handleMessage用于處理Activity所在線程接收到的消息,此處是把當(dāng)前時(shí)間顯示在文本框中。obtainMessage()方法用于從全局的消息池中獲得一個(gè)已有的Message對(duì)象,系統(tǒng)為了加速線程間的消息傳遞,創(chuàng)建了一些全局的消息對(duì)象供各線程使用,這些全局消息對(duì)象稱為全局消息池,使用該方法比重新創(chuàng)建一個(gè)消息對(duì)象的效率高。該方法的第一個(gè)參數(shù)用于指定初始化返回消息的what值。sendMessageDelayed()方法用于在1000毫秒后發(fā)送what值為100的消息,即在顯示完當(dāng)前時(shí)間后的1秒,再發(fā)送一次消息,從而可以每過1秒更新一次文本框的時(shí)間。此處使用100代表該消息類型。2)、需要注意的是:在應(yīng)用程序運(yùn)行時(shí),當(dāng)用戶按Back鍵返回后,盡管Activity進(jìn)入了暫?;蛘咄V沟臓顟B(tài),但是消息的發(fā)送會(huì)依然在后臺(tái)執(zhí)行,因此,程序員需要根據(jù)情況決定是否要停止消息發(fā)送。例如可以在onPause()方法內(nèi)將消息隊(duì)列中的消息移除,并在onResume()方法中重新開始消息發(fā)送。removeMessage(100)方法用于移除消息隊(duì)列中what值為100的全部消息。課堂練習(xí):跳動(dòng)的時(shí)鐘HandlerHandler完成線程間傳遞數(shù)據(jù)使用Handler對(duì)象不但可以給本線程發(fā)送消息,還可以給其它線程發(fā)送消息,前提是需要獲取其它線程中的Handler對(duì)象。線程之間傳遞數(shù)據(jù)在GUI應(yīng)用中十分廣泛,比如后臺(tái)線程正在執(zhí)行具體的數(shù)據(jù)處理,前臺(tái)界面需要顯示出處理的進(jìn)度,典型的就是進(jìn)度對(duì)話框。在這種應(yīng)用中,前臺(tái)線程(一般是指Activity)創(chuàng)建一個(gè)后臺(tái)線程,并把前臺(tái)線程的Handler對(duì)象傳遞給后臺(tái)線程,后臺(tái)線程就可以通過該Handler對(duì)象向前臺(tái)線程發(fā)送消息,報(bào)告后臺(tái)數(shù)據(jù)處理的進(jìn)度。Looper6

Handler6.1使用LooperThread在默認(rèn)情況下,只要run()方法執(zhí)行完畢,線程就結(jié)束。簡(jiǎn)單控制線程不主動(dòng)退出的方法是:在run()方法內(nèi)部加一個(gè)while()循環(huán),這的確也能解決一些問題,對(duì)于那些不需要接收消息而言,基本上夠用了。但在另一些情況下,新建的線程需要接收消息并處理,因此,在新線程中,除了需要添加一個(gè)Handler對(duì)象外,還需要從線程的消息隊(duì)列中取出消息,并負(fù)責(zé)分發(fā)消息,這就需要Looper了。事實(shí)上,Activity內(nèi)部就有一個(gè)Looper,只是Activity是一個(gè)特殊的Thread,操作系統(tǒng)已經(jīng)將其封裝了而已。Looper往往和Handler同時(shí)使用,案例如下所示:6

Handler6.1使用LooperLooper.prepare()用于給該線程創(chuàng)建一個(gè)Looper對(duì)象;Looper.loop()用于開始執(zhí)行Looper對(duì)象,所謂的執(zhí)行就是讓Looper對(duì)象開始讀取線程的消息隊(duì)列,并派

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論