小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

總結(jié)一些關(guān)于android 異步線程通信的知識(shí)

 生活小資訊 2013-03-14
什么時(shí)候使用多線程:
1. 耗時(shí)操作使用多線程, 耗時(shí)操作放在UI線程中會(huì)導(dǎo)致用戶的操作無法得到響應(yīng).
2. 阻塞操作使用多線程, 理由同上.
3. 多核CUP的設(shè)備使用多線程, 可以有效提高CPU的利用率.
4. 并行操作使用多線程.
android中的多線程模型主要涉及的類有:Looper, Handler, MessageQueue, Message等. 


Looper類用來創(chuàng)建消息隊(duì)列. 每個(gè)線程最多只能有一個(gè)消息隊(duì)列, android中UI線程默認(rèn)具有消息隊(duì)列, 但非UI線程在默認(rèn)情況下是不具備消息隊(duì)列的. 如果需要在非UI線程中開啟消息隊(duì)列, 需要調(diào)用Looper.prepare()方法, 在該方法的執(zhí)行過程中會(huì)創(chuàng)建一個(gè)Looper對(duì)象, 而Looper的構(gòu)造函數(shù)中會(huì)創(chuàng)建一個(gè)MessageQueue instance(Looper的構(gòu)造函數(shù)是私有的, 在Looper類之外無法創(chuàng)建其對(duì)象).  此后再為該線程綁定一個(gè)Handler instance, 然后調(diào)用Looper.loop()方法, 就可以不斷的從消息隊(duì)列中取出消息和處理消息了. Looper.myLoop()方法可以得到線程的Looper對(duì)象, 如果為null, 說明此時(shí)該線程尚未開啟消息隊(duì)列.


Handler類用于處理消息. 該類具有四個(gè)構(gòu)造函數(shù):
1. public Handler(). 創(chuàng)建好的Handler instance將綁定在代碼所在的線程的消息隊(duì)列上, 因此一定要確定該線程開啟了消息隊(duì)列, 否則程序?qū)l(fā)生錯(cuò)誤. 使用這個(gè)構(gòu)造函數(shù)創(chuàng)建Handler instance, 一般來說, 我們需要重寫Hanler類的handleMessage()方法, 以便在之后的消息處理時(shí)調(diào)用.
2. public Handler(Callback callback). Callback是Handler內(nèi)部定義的一個(gè)接口, 因此想要使用這個(gè)構(gòu)造函數(shù)創(chuàng)建Handler對(duì)象, 需要自定義一個(gè)類實(shí)現(xiàn)Callback接口, 并重寫接口中定義的handleMessage()方法. 這個(gè)構(gòu)造函數(shù)其實(shí)與無參的構(gòu)造函數(shù)類似, 也要確保代碼所在的線程開啟了消息隊(duì)列. 不同的是在之后處理消息時(shí), 將調(diào)用callback的handleMessage()方法, 而不是Handler對(duì)象的handleMssage()方法.
3. public Handler(Looper looper). 這個(gè)構(gòu)造函數(shù)表示創(chuàng)建一個(gè)Handler instance, 并將其綁定在looper所在的線程上. 此時(shí)looper不能為null. 此時(shí)一般也需要重寫Hanler類的handleMessage()方法
4. public Handler(Looper looper, Callback callback). 可以結(jié)合2和3理解.

MessageQueue類用于表示消息隊(duì)列. 隊(duì)列中的每一個(gè)Message都有一個(gè)when字段, 這個(gè)字段用來決定Message應(yīng)該何時(shí)出對(duì)處理. 消息隊(duì)列中的每一個(gè)Message根據(jù)when字段的大小由小到大排列, 排在最前面的消息會(huì)首先得到處理, 因此可以說消息隊(duì)列并不是一個(gè)嚴(yán)格的先進(jìn)先出的隊(duì)列.

Message類用于表示消息. Message對(duì)象可以通過arg1, arg2, obj字段和setData()攜帶數(shù)據(jù), 此外還具有很多字段. when字段決定Message應(yīng)該何時(shí)出對(duì)處理, target字段用來表示將由哪個(gè)Handler對(duì)象處理這個(gè)消息, next 字段表示在消息隊(duì)列中排在這個(gè)Message之后的下一個(gè)Message, callback字段如果不為null表示這個(gè)Message包裝了一個(gè)runnable對(duì)象, what字段表示code, 即這個(gè)消息具體是什么類型的消息. 每個(gè)what都在其handler的namespace中, 我們只需要確保將由同一個(gè)handler處理的消息的what屬性不重復(fù)就可以.網(wǎng)絡(luò)玩扎金花怎么確保安全性

將消息壓入消息隊(duì)列: Message對(duì)象的target字段關(guān)聯(lián)了哪個(gè)線程的消息隊(duì)列, 這個(gè)消息就會(huì)被壓入哪個(gè)線程的消息隊(duì)列中.

1. 調(diào)用Handler類中以send開頭的方法可以將Message對(duì)象壓入消息隊(duì)列中, 調(diào)用Handler類中以post開頭的方法可以將一個(gè)runnable對(duì)象包裝在一個(gè)Message對(duì)象中, 然后再壓入消息隊(duì)列, 此時(shí)入隊(duì)的Message其callback字段不為null, 值就是這個(gè)runnable對(duì)象. 調(diào)用Handler對(duì)象的這些方法入隊(duì)的Message, 其target屬性會(huì)被賦值為這個(gè)handler對(duì)象.
2. 調(diào)用Mssage對(duì)象的sendToTarget()方法可以將其本身壓入與其target字段(即handler對(duì)象)所關(guān)聯(lián)的消息隊(duì)列中. 
3.將未來得及處理的消息從消息隊(duì)列中刪除:調(diào)用Handler對(duì)象中以remove開頭的方法就可以刪除


從消息隊(duì)列中取出消息并處理消息: 所有在消息隊(duì)列中的消息, 都具有target字段. 消息是在target所關(guān)聯(lián)的線程上被取出和處理的.

1. 如果取出的Message對(duì)象的callback字段不為null, 那么就調(diào)用callback字段的run()方法(callback字段的類型是runnable). 注意此時(shí)并不開啟一個(gè)新的線程運(yùn)行run()方法, 而是直接在handler對(duì)象(即Message的target字段)所關(guān)聯(lián)的線程上運(yùn)行.
2. 如果取出的Message對(duì)象的callback字段為null, 且Handler對(duì)象中的callback字段也為null, 那么這個(gè)消息將由Handler對(duì)象的handleMessage(msg)方法處理. 注意Message對(duì)象的callback字段是Runnable類型的而Handler對(duì)象的callback字段是Callback類型的, Handler對(duì)象的callback字段是在創(chuàng)建Handler instance的時(shí)候指定的, 如果沒有指定則這個(gè)字段為null, 詳見Handler類的四個(gè)構(gòu)造方法.
3. 如果取出的Message對(duì)象的callback字段為null, 且Handler對(duì)象中的callback字段不為null, 那么這個(gè)消息將由Handler對(duì)象中的callback字段的handleMessage方法處理.

線程間通信: 有了以上的敘述, 線程間的通信也就好理解了. 假如一個(gè)handler關(guān)聯(lián)了A線程上的消息隊(duì)列, 那么我們可以在B線程上調(diào)用handler的相關(guān)方法向A線程上的消息隊(duì)列壓入一個(gè)Message, 這個(gè)Message將在A線程上得到處理.

android為我們提供的讓程序運(yùn)行在UI線程的辦法:真錢扎金花

1)、Activity.runOnUiThread(Runnable):如果當(dāng)前線程為ui線程,則立即執(zhí)行;否則,將參數(shù)中的線程操作放入到ui線程的事件隊(duì)列中,等待執(zhí)行。

2)、View.post(Runnable):將操作放入到message隊(duì)列中,如果放入成功,該操作將會(huì)在ui線程中執(zhí)行,并返回true,否則返回false

3)、View.postDelayed(Runnable, long)跟第三條基本一樣,只不過添加了一個(gè)延遲時(shí)間。

4)、android1.5以后為我們提供了一個(gè)工具類來搞定這個(gè)問題AsyncTask.

5)、Handler、Thread、message解決

6)、AsyncTask異步任務(wù)類

AsyncTask是抽象類,定義了三種泛型類型 Params,Progress,Result。

Params 啟動(dòng)任務(wù)執(zhí)行的輸入?yún)?shù),比如HTTP請(qǐng)求的URL

Progress 后臺(tái)任務(wù)執(zhí)行的百分比。

Result 后臺(tái)執(zhí)行任務(wù)最終返回的結(jié)果,比如String

實(shí)現(xiàn)的這法

1) 子類化AsyncTask

2) 實(shí)現(xiàn)AsyncTask中定義的下面一個(gè)或幾個(gè)方法

onPreExecute(),該方法將在執(zhí)行實(shí)際的后臺(tái)操作前被UI thread調(diào)用??梢栽谠摲椒ㄖ凶鲆恍?zhǔn)備工作,如在界面上顯示一個(gè)進(jìn)度條。

doInBackground(Params…),將在onPreExecute 方法執(zhí)行后馬上執(zhí)行,該方法運(yùn)行在后臺(tái)線程中。這里將主要負(fù)責(zé)執(zhí)行那些很耗時(shí)的后臺(tái)計(jì)算工作。可以調(diào)用 publishProgress方法來更新實(shí)時(shí)的任務(wù)進(jìn)度。該方法是抽象方法,子類必須實(shí)現(xiàn)。

onProgressUpdate(Progress…),在publishProgress方法被調(diào)用后,UI thread將調(diào)用這個(gè)方法從而在界面上展示任務(wù)的進(jìn)展情況,例如通過一個(gè)進(jìn)度條進(jìn)行展示。

onPostExecute(Result),在doInBackground 執(zhí)行完成后,onPostExecute 方法將被UI thread調(diào)用,后臺(tái)的計(jì)算結(jié)果將通過該方法傳遞到UI thread.

為了正確的使用AsyncTask類,以下是幾條必須遵守的準(zhǔn)則:

1) Task的實(shí)例必須在UI thread中創(chuàng)建

2) execute方法必須在UI thread中調(diào)用

3) 不要手動(dòng)的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)這幾個(gè)方法

4) 該task只能被執(zhí)行一次,否則多次調(diào)用時(shí)將會(huì)出現(xiàn)異常

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多