• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    Android應(yīng)用程序中多線程應(yīng)用的方法研究

    2014-04-29 00:00:00肖柏昀

    摘 要:在Android應(yīng)用程序中,如果UI線程(主線程)處理事件占用的時(shí)間過(guò)長(zhǎng),就會(huì)出現(xiàn)ANR(應(yīng)用程序無(wú)響應(yīng))異常。因此,為了確保用戶順暢的操作體驗(yàn),我們需要將耗時(shí)長(zhǎng)的任務(wù)(如:訪問(wèn)網(wǎng)絡(luò)獲取數(shù)據(jù)、大量的數(shù)據(jù)計(jì)算)分配給后臺(tái)線程處理。其中涉及到UI線程與非UI線程信息交互等相關(guān)問(wèn)題。本文將主要討論如何最佳構(gòu)建應(yīng)用程序來(lái)提高響應(yīng)性能并避免ANR異常。

    關(guān)鍵詞:Android;ANR異常;多線程技術(shù);異步任務(wù)

    中圖分類號(hào):TP311.52

    Android是基于Linux平臺(tái)的開(kāi)源手機(jī)操作系統(tǒng),目前已廣泛地使用于手機(jī)等移動(dòng)設(shè)備。由于Android的開(kāi)源性,基于Android應(yīng)用軟件的開(kāi)發(fā)也有著很好的市場(chǎng)前景。為保證Android應(yīng)用軟件的良好用戶體驗(yàn),合理地分配UI線程和后臺(tái)線程中所執(zhí)行的任務(wù)是極為重要的。因此,在開(kāi)發(fā)Android應(yīng)用程序時(shí),引入多線程技術(shù)可以有效地明確應(yīng)用程序的結(jié)構(gòu),保證應(yīng)用程序的靈活性,降低任務(wù)間的耦合度,使得所開(kāi)發(fā)的應(yīng)用軟件能夠更加高效地運(yùn)行。

    1 Android的相關(guān)知識(shí)

    1.1 Android基本組件

    一個(gè)Android應(yīng)用程序由松散耦合的組件組成,并由應(yīng)用程序清單綁定到一起。它主要由以下五個(gè)基本模塊構(gòu)成:

    活動(dòng)(Activity):Android應(yīng)用程序的核心,形成顯示信息的圖形用戶接口并響應(yīng)用戶事件。

    服務(wù)(Service):一直在后臺(tái)運(yùn)行,可以更新數(shù)據(jù)源和可見(jiàn)活動(dòng)并觸發(fā)通知。

    內(nèi)容(Context):用來(lái)管理和共享應(yīng)用數(shù)據(jù)庫(kù),實(shí)現(xiàn)多個(gè)程序之間的數(shù)據(jù)共享。

    意圖(Intent):一個(gè)應(yīng)用程序之間傳遞消息的橋梁。通過(guò)意圖,可以在系統(tǒng)范圍內(nèi)向目標(biāo)活動(dòng)或者服務(wù)廣播消息,以說(shuō)明執(zhí)行某個(gè)動(dòng)作的意圖。

    廣播接收器(Broadcast Receiver):通過(guò)創(chuàng)建和注冊(cè)廣播接收器,應(yīng)用程序可以監(jiān)聽(tīng)到匹配特定過(guò)濾器的意圖廣播,廣播接收器會(huì)自動(dòng)啟動(dòng)應(yīng)用程序響應(yīng)某個(gè)意圖,這個(gè)特點(diǎn)使其成為事件驅(qū)動(dòng)應(yīng)用程序的最佳選擇。[1]

    1.2 Android事件處理

    在絕大部分情況下,應(yīng)用程序需要及時(shí)對(duì)用戶動(dòng)作做出響應(yīng)。因此,Android應(yīng)用程序與用戶的交互是十分重要的。要實(shí)現(xiàn)用戶與應(yīng)用程序的交互,就需要編寫(xiě)Java代碼來(lái)創(chuàng)建事件處理。

    Android事件處理是一種“委托事件處理模型”(Delegation Event Model),分為“事件來(lái)源”(Event Source)和處理事件的“監(jiān)聽(tīng)者”(listener)對(duì)象。當(dāng)事件發(fā)生時(shí),注冊(cè)的監(jiān)聽(tīng)者對(duì)象可以接收事件,然后調(diào)用相關(guān)方法進(jìn)行處理,監(jiān)聽(tīng)者是一個(gè)委托處理設(shè)置事件的對(duì)象。[2]

    2 Android系統(tǒng)中多線程信息交互具體方法

    2.1 多線程技術(shù)的使用

    Android的UI線程主要負(fù)責(zé)處理用戶的按鍵事件、用戶觸屏?xí)r間及屏幕繪圖事件等,因此其他的操作是不能夠阻塞UI線程的,否則UI界面會(huì)停止響應(yīng)。Android系統(tǒng)默認(rèn)約定當(dāng)UI線程阻塞超過(guò)20秒時(shí),將會(huì)引發(fā)應(yīng)用程序無(wú)響應(yīng)異常(ANR)。

    為避免上述現(xiàn)象的發(fā)生,Android建議將耗時(shí)的操作放在新的子線程中完成。Android開(kāi)發(fā)框架中主要提供了兩種解決方法(以通過(guò)網(wǎng)絡(luò)下載大量資源為例):

    (1)首先,程序需要啟動(dòng)一個(gè)新的子線程來(lái)獲取下載資源文件,資源獲取結(jié)束后通過(guò)Handler機(jī)制發(fā)送消息(Message),并同時(shí)在UI線程中處理消息,從而達(dá)到異步線程中處理事件的效果,然后通過(guò)Handler Message方法來(lái)更新線程。

    (2)使用Android中提供的AsyncTask方式來(lái)完成異步操作。AsyncTask是使用java.util.concurrent框架來(lái)管理線程以及任務(wù)的執(zhí)行的,concurrent框架是一個(gè)非常成熟、高效的框架,經(jīng)過(guò)了嚴(yán)格的測(cè)試。這說(shuō)明AsyncTask的設(shè)計(jì)很好的解決了匿名線程存在的問(wèn)題。[3]

    當(dāng)Android應(yīng)用程序啟動(dòng)主線程時(shí),主線程主要負(fù)責(zé)處理與UI相關(guān)的事件,并將相關(guān)的事件分配給對(duì)應(yīng)組件進(jìn)行處理。為了保證線程的安全性,Android規(guī)定:只允許主線程修改Activity中的組件。但是,在實(shí)際開(kāi)發(fā)中,很可能需要啟動(dòng)新的子線程修改UI組件的屬性,這就需要利用到Handler的消息傳遞機(jī)制。

    2.2 Handler消息傳遞機(jī)制

    Handler類主要包括兩個(gè)作用:在新啟動(dòng)的線程中發(fā)送消息;在主線程中獲取、處理消息。通過(guò)回調(diào)的方式,主線程能夠處理新啟動(dòng)線程所發(fā)送的消息。當(dāng)新啟動(dòng)的線程發(fā)送消息時(shí),消息會(huì)發(fā)送到與之關(guān)聯(lián)的MessageQueue,而handler會(huì)不斷從MessageQueue中獲取并處理消息。

    下面介紹與Handler類工作的三個(gè)組件:

    Message:Handler接收和處理的消息對(duì)象。

    Looper:每個(gè)線程只能擁有一個(gè)Looper。它的loop方法負(fù)責(zé)讀取MessageQueue中的消息,讀到消息后就把消息交給發(fā)送該消息的Handler進(jìn)行處理。

    MessageQueue:消息隊(duì)列,它采用先進(jìn)先出的方式來(lái)管理Message。

    處理過(guò)程如圖1所示。

    圖1

    Looper對(duì)象與對(duì)應(yīng)的子線程綁定,在初始化Looper時(shí),會(huì)創(chuàng)建一個(gè)與之相關(guān)聯(lián)的MessageQueue,這個(gè)MessageQueue負(fù)責(zé)管理該子線程的消息。

    每一個(gè)線程只能擁有一個(gè)Looper,它的loop方法負(fù)責(zé)讀取MessageQueue中的消息,讀到消息之后將其交給Handler處理。為確保Handler能夠正常工作,當(dāng)前的線程必須有一個(gè)MessageQueue,而MessageQueue又是由對(duì)應(yīng)的Looper負(fù)責(zé)管理的,所以啟動(dòng)一個(gè)子線程時(shí),必須為其創(chuàng)建一個(gè)Looper對(duì)象并啟動(dòng)它。

    需要說(shuō)明的是,在主線程中,系統(tǒng)已經(jīng)初始化了一個(gè)Looper,因此只需創(chuàng)建一個(gè)Handler即可。[4]

    2.3 AsyncTask

    相對(duì)于Handler消息傳遞機(jī)制,AsyncTask更輕量級(jí)一些,適用于簡(jiǎn)單的異步處理,不需要借助線程和Handler即可實(shí)現(xiàn)。

    AsyncTask是抽象類,它定義了如下三種泛型類型:

    (1)Params:?jiǎn)?dòng)任務(wù)執(zhí)行的輸入?yún)?shù)的類型。

    (2)Progress:后臺(tái)任務(wù)完成的進(jìn)度值的類型。

    (3)Result:后臺(tái)執(zhí)行任務(wù)完成后返回結(jié)構(gòu)的類型。

    使用AsyncTask主要分為三步:

    (1)創(chuàng)建AsyncTask的子類,并為三個(gè)泛型參數(shù)指定類型;

    (2)實(shí)現(xiàn)AsyncTask下面的幾個(gè)方法:

    doInBackground(Params…):重寫(xiě)該方法指定后臺(tái)線程將要完成的任務(wù)。

    onProgressUpdate(Progress...values):在調(diào)用publishProgress(Progress...values)時(shí),此方法被執(zhí)行,直接將進(jìn)度信息更新到UI組件上。

    onPreExecute():該方法在執(zhí)行后臺(tái)耗時(shí)操作前被調(diào)用,通常用于完成初始化的準(zhǔn)備工作。

    onPostExecute(Result result):當(dāng)doInBackground()完成后,系統(tǒng)調(diào)用該方法,將后臺(tái)計(jì)算的結(jié)果傳遞到UI線程中。

    (3)調(diào)用AskncTask的子類的execute()方法執(zhí)行耗時(shí)的任務(wù)。

    Android提供的AsyncTask類實(shí)質(zhì)上是Handler與Thread的封裝。因此,我們可以直接繼承AsyncTask類,并在類中實(shí)現(xiàn)相關(guān)的異步操作,利用類中提供的接口實(shí)現(xiàn)UI進(jìn)度的更新。

    2.4 Handler機(jī)制與AsyncTask的比較

    Handler機(jī)制與AsyncTask均能夠在Android中實(shí)現(xiàn)異步任務(wù)機(jī)制,由于它們各自不同的特點(diǎn)適用的環(huán)境也不盡相同。

    Handler機(jī)制中涉及到Handler、Looper、Message、Thread四個(gè)對(duì)象,能夠清晰地將不同的后臺(tái)任務(wù)進(jìn)行劃分,有利于理解各個(gè)任務(wù)的實(shí)質(zhì)與功能,對(duì)于整個(gè)過(guò)程的控制比較精細(xì)。但是,當(dāng)其用于處理單一的后臺(tái)任務(wù)時(shí),相比于AsyncTask,其結(jié)構(gòu)顯得相對(duì)復(fù)雜,代碼段也較為臃腫,不易精確地控制任務(wù)。

    AsyncTask的實(shí)現(xiàn)原理較為簡(jiǎn)單,因此在使用其實(shí)現(xiàn)異步任務(wù)時(shí)會(huì)更加快捷。但是,當(dāng)有多個(gè)異步操作需要訪問(wèn)或變更UI組件時(shí),處理過(guò)程就會(huì)變得復(fù)雜。

    3 結(jié)束語(yǔ)

    本文就Android操作系統(tǒng)應(yīng)用層的工作機(jī)制做了大致的介紹,并且分析了利用多線程技術(shù)來(lái)提高應(yīng)用軟件相應(yīng)性能以及避免ANR異常的方法。具體說(shuō)明了Android框架中2種用于避免UI線程阻塞的機(jī)制即Handler消息傳遞機(jī)制和異步任務(wù)機(jī)制,并且對(duì)兩者做出了簡(jiǎn)要的比較。

    總的來(lái)說(shuō),開(kāi)發(fā)Android應(yīng)用程序時(shí)需要利用上述的兩種機(jī)制將耗時(shí)多的任務(wù)分配給后臺(tái)的子線程,這樣能夠減輕UI線程的負(fù)擔(dān),減小發(fā)生ANR的可能性,并進(jìn)一步提高用戶體驗(yàn)。

    參考文獻(xiàn):

    [1]閆偉,葉建栲.多線程技術(shù)在Android手機(jī)開(kāi)發(fā)中的應(yīng)用[J].信息通信,2012(01).

    [2]陳會(huì)安.Android SDK程序設(shè)計(jì)與范例[M].北京:清華學(xué)出版社,2012.

    [3]楊杰.基于Android的多線程處理技術(shù)[J].電腦知識(shí)與技術(shù),2013.

    [4]李剛.瘋狂Android講義第二版[M].北京:電子工業(yè)出版社,2013.

    作者簡(jiǎn)介:肖柏昀(1993.09-),女,湖北人,研究方向:計(jì)算機(jī)應(yīng)用。

    作者單位:華中師范大學(xué)計(jì)算機(jī)學(xué)院,武漢 430079

    麦盖提县| 夏邑县| 南木林县| 徐闻县| 高碑店市| 兰西县| 嵊州市| 松桃| 栾城县| 新密市| 庄浪县| 麦盖提县| 金寨县| 鄂托克旗| 馆陶县| 当涂县| 安溪县| 邳州市| 兴和县| 板桥市| 德令哈市| 志丹县| 沧源| 池州市| 辽阳市| 中西区| 宜君县| 农安县| 射洪县| 湘阴县| 安塞县| 连城县| 定襄县| 兴化市| 汉沽区| 巴青县| 唐河县| 鲁甸县| 鄂伦春自治旗| 礼泉县| 昔阳县|