91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中同步與異步的關系是什么

發布時間:2021-06-26 14:46:30 來源:億速云 閱讀:226 作者:Leah 欄目:大數據

本篇文章為大家展示了Android中同步與異步的關系是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

android 只有UI線程可以刷新界面,其他副線程不行,這樣就需要副線程通過通信消息修改刷新和修改界面。 

有2方式可以實現: 
AsyncTask,Handle 
AsyncTask 
android提供的簡單用于異步通訊的線程
主要四個實現接口: 
    onPreExecute(), 該方法將在執行實際的后臺操作前被UI 線程調用。可以在該方法中做一些準備工作,如在界面上顯示一個進度條,或者一些控件的實例化,這個方法可以不用實現。 
    doInBackground(Params...), 將在onPreExecute 方法執行后馬上執行,該方法運行在后臺線程中。這里將主要負責執行那些很耗時的后臺處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。 
    onProgressUpdate(Progress...),在publishProgress方法被調用后,UI 線程將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。 
    onPostExecute(Result), 在doInBackground 執行完成后,onPostExecute 方法將被UI 線程調用,后臺的計算結果將通過該方法傳遞到UI 線程,并且在界面上展示給用戶. 
    onCancelled(),在用戶取消線程操作的時候調用。在主線程中調用onCancelled()的時候調用。 

調用注意 
1) Task的實例必須在UI 線程中創建 
2) execute方法必須在UI 線程中調用 
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法,需要在UI線程中實例化這個task來調用。 
4) 該task只能被執行一次,否則多次調用時將會出現異常。
5)doInBackground方法返回值和onPostExecute的參數必須對應,這兩個參數在AsyncTask聲明的泛型參數列表中指定,第一個為doInBackground接受的參數,第二個為顯示進度的參數,第第三個為doInBackground返回和onPostExecute傳入的參數。 
可以看到這個線程有副線程的接口處理doInBackground,也有UI線程的接口處理onProgressUpdate,在啟動線程時可以傳入泛類參數。 

Handler 
Handler類可以看做工具類,用來向消息隊列中插入消息的。實例化時自動綁定調用的線程Looper,當處理消息時在該線程中執行。利用這個特性,副線程發送消息,接受消息后在主線程處理,達到主線程和副線程的通訊。

在Android里可以這么理解,因為在android里你可以把UI界面當做主線程,你不能因為下載東西就一直顯示下載,用戶體驗不好,也不被google容許,所以你點擊下載就是開啟子線程去下載了,手機頁面該看什么你就看什么,等下載好子線程就發個message給handler它來更新UI,在你的手機界面顯示或彈出一個下載好了的消息,如果不用handler下載好了你也不知道,還得自己去看。Handler和Thread:子線程是不能更新UI的,所以用Thread開啟子線程后,如果需要更新UI,就通過Handler來更新UI.

而AsyncTask 中:

doInBackground(Params…) 屬于子線程,后臺執行,比較耗時的操作都可以放在這里。注意這里不能直接操作UI。此方法在后臺線程執行,完成任務的主要工作,通常需要較長的時間。在執行過程中可以 調用publicProgress(Progress…)來更新任務的進度。

onPostExecute(Result)  相當于Handler 處理UI的方式,在這里面可以使用在doInBackground 得到的結果處理操作UI。 此方法在主線程執行,任務執行的結果作為此方法的參數返回

 
looper類是用來封裝消息循環和消息隊列的一個類。 
(1) Looper類用來為一個線程開啟一個消息循環。 
    默認情況下android中新誕生的線程是沒有開啟消息循環的。(主線程除外,主線程系統會自動為其創建Looper對象,開啟消息循環。) 
    Looper對象通過MessageQueue來存放消息和事件。一個線程只能有一個Looper,對應一個MessageQueue。
(2) 通常是通過Handler對象來與Looper進行交互的。Handler可看做是Looper的一個接口,用來向指定的Looper發送消息及定義處理方法。 
    默認情況下Handler會與其被定義時所在線程的Looper綁定,比如,Handler在主線程中定義,那么它是與主線程的Looper綁定。 
mainHandler = new Handler() 等價于new Handler(Looper.myLooper()). 
Looper.myLooper():獲取當前進程的looper對象,類似的 Looper.getMainLooper() 用于獲取主線程的Looper對象。 
(3) 在非主線程中直接new Handler() 會報如下的錯誤: 
E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception 
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
原因是非主線程中默認沒有創建Looper對象,需要先調用Looper.prepare()啟用Looper。 
(4) Looper.loop(); 讓Looper開始工作,從消息隊列里取消息,處理消息。 
    注意:寫在Looper.loop()之后的代碼不會被執行,這個函數內部應該是一個循環,當調用mHandler.getLooper().quit()后,loop才會中止,其后的代碼才能得以運行。 
(5) 基于以上知識,可實現主線程給子線程(非主線程)發送消息。 
    把下面例子中的mHandler聲明成類成員,在主線程通過mHandler發送消息即可。 

總結,一般都是綁定主線程的handler,達到通訊目的,在副線程中發送消息。若要創建副線程中綁定handler,則必須先創建副線程的looper,已達到循環發送消息的目的。有兩種方式達到這個目的: 
1、通過handler+Looper兩個類。 
2、通過HandlerThread這個類,這個是android提供的利用Looper和Handler繼承Thread完成。 

上述內容就是Android中同步與異步的關系是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荔波县| 新乡市| 互助| 正宁县| 紫金县| 湄潭县| 湟中县| 沧源| 临沧市| 正宁县| 汉川市| 桃源县| 德安县| 山东| 上思县| 皮山县| 鱼台县| 乃东县| 呼伦贝尔市| 米易县| 大同县| 麻城市| 元阳县| 霸州市| 射洪县| 剑阁县| 郸城县| 巴东县| 上栗县| 孝昌县| 安陆市| 黄浦区| 三门县| 繁昌县| 岢岚县| 鄂温| 五指山市| 广汉市| 当涂县| 桓仁| 平陆县|