您好,登錄后才能下訂單哦!
Android 使用AsyncTask設(shè)置請(qǐng)求超時(shí)的注意事項(xiàng)
final AsyncTaskTools task = new AsyncTaskTools(dialog, doTask, result, context); mTask.execute("藍(lán)牙讀卡"); new Thread() { public void run() { try { /** * 在這里你可以設(shè)置超時(shí)時(shí)間, * 切記:這段代碼必須放到線程中執(zhí)行,因?yàn)椴环艈为?dú)的線程中執(zhí)行的話該方法會(huì)凍結(jié)UI線程 * 直接導(dǎo)致onPreExecute()方法中的彈出框不會(huì)立即彈出 */ mTask.get(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); Log.e(TAG, "異常1"); } catch (ExecutionException e) { e.printStackTrace(); Log.e(TAG, "異常2"); } catch (TimeoutException e) { e.printStackTrace(); Log.e(TAG, "異常3"); /** * 如果在doInBackground中的代碼執(zhí)行的時(shí)間超出10秒則會(huì)出現(xiàn)這個(gè)異常, * 所以這里就成為你處理異常操作的唯一途徑, * 備注:這里是不能夠處理UI操作的,如果處理UI操作則會(huì)出現(xiàn)崩潰異常,可以使用handler,向handler發(fā)送消息然后在handler中接受消息并處理 * UI更新操作 */ Message message = new Message(); message.what = 0; mHandler.sendMessage(message); } } }.start();
2.handler詳解
一個(gè)Handler允許你發(fā)送和處理消息(Message)以及與一個(gè)線程的消息隊(duì)列相關(guān)的Runnable對(duì)象。每個(gè)Handler實(shí)例都和單個(gè)線程以及該線程的消息隊(duì)列有關(guān)。當(dāng)你創(chuàng)建了一個(gè)新Handler,它就會(huì)和創(chuàng)建它的線程/消息隊(duì)列綁定,在那以后,它就會(huì)傳遞消息以及runnable對(duì)象給消息隊(duì)列,然后執(zhí)行它們。
需要使用Handler有兩大主要的原因:
(1)在將來的某個(gè)時(shí)間點(diǎn)調(diào)度處理消息和runnable對(duì)象;
(2)將需要執(zhí)行的操作放到其他線程之中,而不是自己的;
調(diào)度處理消息是通過調(diào)用post(Runnable), postAtTime(Runnable, long),postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message),sendMessageAtTime(Message, long)和sendMessageDelayed(Message,long)等方法完成的。其中的post版本的方法可以讓你將Runnable對(duì)象放進(jìn)消息隊(duì)列;sendMessage版本的方法可以讓你將一個(gè)包含有bundle對(duì)象的消息對(duì)象放進(jìn)消息隊(duì)列,然后交由handleMessage(Message)方法處理。(這個(gè)需要你復(fù)寫Handler的handleMessage方法)
Handler在實(shí)際開發(fā)中是很常用的,主要是用來接收子線程發(fā)送的數(shù)據(jù),然后主線程結(jié)合此數(shù)據(jù)來更新界面UI。
Android應(yīng)用程序啟動(dòng)時(shí),他會(huì)開啟一個(gè)主線程(也就是UI線程),管理界面中的UI控件,進(jìn)行事件派發(fā),比如說:點(diǎn)擊一個(gè)按鈕,Android會(huì)分發(fā)事件到Button上從而來響應(yīng)你的操作。但是當(dāng)你需要執(zhí)行一個(gè)比較耗時(shí)的操作的話,例如:進(jìn)行IO操作,網(wǎng)絡(luò)通信等等,若是執(zhí)行時(shí)間超過5s,那么Android會(huì)彈出一個(gè)“經(jīng)典”的ANR無響應(yīng)對(duì)話框,然后提示按“Force quit”或是“Wait”。解決此類問題的方法就是:我們把一些耗時(shí)的操作放到子線程中去執(zhí)行。但因?yàn)樽泳€程涉及到UI更新,而Android主線程是線程不安全的,所以更新UI的操作只能放在主線程中執(zhí)行,若是放在子線程中執(zhí)行的話很會(huì)出問題。所以這時(shí)就需要一種機(jī)制:主線程可以發(fā)送“命令/任務(wù)”給子線程執(zhí)行,然后子線程反饋執(zhí)行結(jié)果;
一、什么是handler?
答:handler是Android給我們提供用來更新UI的一套機(jī)制,也是一套消息處理機(jī)制,我們可以發(fā)消息,也可以通過它 處理消息。
二、那為什么要用handler呢?我能不能不用?
答:我在網(wǎng)上搜了下,給我的答案是,肯定是不行的。因?yàn)閍ndroid在設(shè)計(jì)的時(shí)候就封裝了一套消息創(chuàng)建、傳遞、處理。如果不遵循就不能更新UI信息,就會(huì)報(bào)出異常。
三、Android為什么要設(shè)計(jì)只能用handler機(jī)制更新UI呢?
答:最根本的目的就是為了解決多線程并發(fā)的問題!
打個(gè)比方,如果在一個(gè)activity中有多個(gè)線程,并且沒有加鎖,就會(huì)出現(xiàn)界面錯(cuò)亂的問題。但是如果對(duì)這些更新UI的操作都加鎖處理,又會(huì)導(dǎo)致性能下降。
處于對(duì)性能的問題考慮,Android給我們提供這一套更新UI的機(jī)制我們只需要遵循這種機(jī)制就行了。不用再去關(guān)系多線程的問題,所有的更新UI的操作,都是在主線程的消息隊(duì)列中去輪訓(xùn)的。
四、handler、Looper、MessageQueue的原理是什么?
答:大家都知道handler的作用有兩個(gè),發(fā)送消息和處理消息。而handler發(fā)送的消息必須被送到指定MessageQueue(消息隊(duì)列)中,也就是說,如果想讓handler正常工作,就必須有一個(gè)MessageQueue(消息隊(duì)列),不過MessageQueue(消息隊(duì)列)是由Looper來關(guān)系。所以也可以說想讓handler正常工作,必須在當(dāng)前線程中有一個(gè)Looper對(duì)象。(請(qǐng)認(rèn)真讀)
1、來看一下Looper提供的構(gòu)造器源碼,如圖:
你會(huì)發(fā)現(xiàn)該構(gòu)造器用到的是private(私有化),告訴你的就是程序員你不能通過構(gòu)造方法創(chuàng)建looper對(duì)象,而在方法中Looper創(chuàng)建了一個(gè)與關(guān)聯(lián)的MessageQueue,這個(gè)MessageQueue就是用來管理Message(handler接收和處理的消息對(duì)象)!
2、為了保證當(dāng)前線程有Looper對(duì)象,可以有兩種情況處理。(瘋狂的Android講義224頁(yè))
(1)主ui線程啟動(dòng),系統(tǒng)就初始化了一個(gè)Looper對(duì)象,只要在程序中直接創(chuàng)建handler即可,然后用handler發(fā)送和處理消息。
(2)程序員自己創(chuàng)建的線程,這個(gè)時(shí)候就要自己手動(dòng)創(chuàng)建一個(gè)Looper對(duì)象了,創(chuàng)建Looper對(duì)象調(diào)用它的prepare()。prepare()方法 是為了保證每個(gè)線程最多一個(gè)Looper對(duì)象。
prepare()方法 源碼如圖。
然后用Looper.loop()啟動(dòng)它。此時(shí)loop()方法就會(huì)使用一個(gè)死循環(huán)不斷地取出MessageQueue()中的消息,并將消息分給所對(duì)應(yīng)的Handler處理。
總結(jié)一下吧:
-1:Looper的作用:每個(gè)線程只有一個(gè)Looper,他負(fù)責(zé)管理MessageQueue,會(huì)不斷的從MessageQueue取出消息,分發(fā)給對(duì)象 的handler
-2:MessageQueue的作用:由Looper管理,而MessageQueue則采用先進(jìn)的方法來管理Message!
-3:Handler的作用:它把消息發(fā)送給Looper管理的MessageQueue,并負(fù)責(zé)處理Looper分發(fā)給他的消息。
六、Android在子線程更新UI的最常見的五種方式
1、runOnUiThread()方法
2、handler.post()方法
3、handler.sendMessage()方法
4、view.post()方法。
5、view postDelayed(Runnable,long)
總結(jié)
以上所述是小編給大家介紹的Android 異步任務(wù) 設(shè)置 超時(shí)使用handler更新通知功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。