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