張旭輝
【關(guān)鍵詞】多線程 消息 AsyncTask類
1 引言
隨著移動(dòng)平臺(tái)走入人們的視野,移動(dòng)平臺(tái)的開發(fā)越來越為大家所熟悉,而多線程作為安卓開發(fā)中非常重要部分,在很多應(yīng)用程序都是不可或缺的。
2 線程的概念
2.1 進(jìn)程與線程
進(jìn)程的概念想必大家都比較熟悉,一個(gè)進(jìn)程就是一個(gè)執(zhí)行中的程序,而每一個(gè)進(jìn)程都有自己獨(dú)立的內(nèi)存空間、系統(tǒng)資源,每一個(gè)進(jìn)程的內(nèi)部數(shù)據(jù)和狀態(tài)都是完全獨(dú)立的。
與進(jìn)程相同的是,線程也是一段具有某個(gè)特定功能的代碼,是單個(gè)順序的流控制。但不同的是,同類的多個(gè)線程共享內(nèi)存空間和系統(tǒng)資源,所以系統(tǒng)在線程之間切換時(shí),占用資源比進(jìn)程小,因此線程也被稱為輕量級(jí)進(jìn)程。
多線程指的是在單個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程,以執(zhí)行不同的功能。這使得一個(gè)程序的多行語句看上去好像在同時(shí)運(yùn)行。
2.2 實(shí)現(xiàn)線程的兩種方式
當(dāng)一個(gè)安卓程序第一次啟動(dòng)時(shí),會(huì)默認(rèn)啟動(dòng)一個(gè)主線程,在主線程中主要負(fù)責(zé)處理與UI相關(guān)的事件,包括屏幕繪制、事件響應(yīng)等,并把相關(guān)的事件分發(fā)到對(duì)應(yīng)的組件進(jìn)行處理。因此主線程通常又被叫做UI線程。
在Java中若想新增線程主要通過兩種方式:一是繼承Thread類,一是實(shí)現(xiàn)Runnable接口,無論是哪種方式,都將實(shí)現(xiàn)線程的核心方法run,通常將需要線程處理的事情都放在run方法中,當(dāng)啟動(dòng)線程時(shí)會(huì)自動(dòng)調(diào)用run方法。
3 安卓開發(fā)中的多線程
3.1 Thread+Handler+Message結(jié)構(gòu)
我們以實(shí)現(xiàn)Runnable接口的方式定義線程類,代碼如下。
執(zhí)行如上代碼時(shí)并不能實(shí)現(xiàn)我們想要的效果,反而會(huì)發(fā)生異常使程序崩潰退出。這是因?yàn)樵诎沧恐腥粝敫耈I則必須由創(chuàng)建它的線程來完成。由于我們?cè)诔绦蛑袆?chuàng)建了新的線程,所以程序中就存在主線程和子線程。主線程的職責(zé)是創(chuàng)建、顯示和更新UI控件、處理UI事件、啟動(dòng)子線程,而子線程則負(fù)責(zé)計(jì)算時(shí)間以及向主線程發(fā)出更新UI消息,而不是直接更新UI。但問題是子線程和主線程如何通信呢?在Android中提供了Message作為消息的載體,線程將一個(gè)個(gè)的消息加入到消息隊(duì)列中,Android中又提供了Handler類來對(duì)消息進(jìn)行處理,例如修改UI就可以在Handler中實(shí)現(xiàn)。
在線程類中將修改UI改為發(fā)送消息。
hand.sendMessage(msg); //發(fā)送消息,hand為自定義的Handler類對(duì)象
3.2 AsyncTask類
為了能夠?qū)崿F(xiàn)多線程,Android提供了AsyncTask類,AsyncTask類中包括如下方法。
3.2.1 onPreExecute()
在線程被調(diào)用后立即執(zhí)行,一般用來在執(zhí)行后臺(tái)任務(wù)前對(duì)UI做一些初始化。
3.2.2 doInBackground(Params... params)
在onPreExecute()完成后立即執(zhí)行,用于執(zhí)行較為復(fù)雜的操作,此方法將接收輸入?yún)?shù)和返回計(jì)算結(jié)果。在執(zhí)行過程中可以調(diào)用publishProgress(Progress... values)來更新進(jìn)度信息。
3.2.3 onProgressUpdate(Progress... values)
在調(diào)用publishProgress(Progress... values)時(shí),此方法被執(zhí)行,直接將進(jìn)度信息更新到UI組件上。
3.2.4 onPostExecute(Result result)
當(dāng)后臺(tái)操作結(jié)束時(shí),此方法將會(huì)被調(diào)用,計(jì)算結(jié)果將做為參數(shù)傳遞到此方法中,直接將結(jié)果顯示到UI組件上。
所有方法均不需要手動(dòng)調(diào)用,其中doInBackground(Params... params)中不能修改UI界面。
4 結(jié)論
在安卓開發(fā)中多線程是非常重要的操作,安卓中主要提供了兩種方式來實(shí)現(xiàn)多線程:消息隊(duì)列加Handler的方式和AsyncTask類的方式,兩種方式各有優(yōu)勢(shì),可以根據(jù)實(shí)際案例進(jìn)行選擇。