Android Handler機制理解和AsyncTask使用小記

Android Handler機制理解和AsyncTask使用小記

這是一篇淺入淺出的文章,對handler的使用和問題進行了一個總結,推薦看文章的你本身動手去練習,記憶和理解會更深入一點。java

  1. Handler的概念

咱們先看一下Handler的百科介紹:bash

Handler主要用於異步消息的處理:當發出一個消息以後,首先進入一個消息隊列,發送消息的函數即刻返回,而另一個部分在消息隊列中逐一將消息取出,
而後對消息進行處理,也就是發送消息和接收消息不是同步的處理。 這種機制一般用來處理相對耗時比較長的操做。 
複製代碼

比較難明白,咱們先將概念拆分開理解,放下前面關於消息的部分,先着重看最後一句:處理相對耗時較長的操做。異步

在Android中,主線程中不能執行耗時操做,否則可能會形成ANR等問題,只能在子線程來進行。好比須要下載一個圖片並顯示到界面上,那麼直接按照邏輯,下載圖片是可能耗時的操做,新建一個線程執行下載,而後將下載的圖片傳入界面對應的視圖中,代碼以下:ide

new Thread(){
    @Override
    public void run() {
        super.run();
        final Bitmap bitmap = downloadImg();//下載圖片,返回bitmap
        ivImg.setImageBitmap(bitmap);//傳入下載的圖片到視圖
    }
};
複製代碼

邏輯是正確的,但操做不對,程序沒法運行。函數

由於在Android中,只有主線程能更新UI,因此主線程也叫UI線程,子線程中是不能更新UI的。這時候咱們就能夠用到Handler了,Handler能夠做爲Android更新UI的一套機制,正確的操做代碼以下:post

Handler handler = new Handler(); 
new Thread(){
    @Override
    public void run() {
        super.run();
        final Bitmap bitmap = downloadImg();//下載圖片,返回bitmap
        handler.post(new Runnable() {
            @Override
            public void run() {
                ivImg.setImageBitmap(bitmap);//經過Handler通知主線程更新UI
            }
        })
    }
};
複製代碼

能夠看到,UI的操做放被到了Runnable對象中,而後利用Handler.post(Runnable)實現了UI的更新,能夠簡單理解Handler爲一個傳信者,將子線程中須要更新UI的信息傳入主線程中進行。spa

這是Handler的一種使用方法,經過post(Runnable),第二種是sendMessage()方式,示例以下:線程

mHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if(msg==1){
            tvText.setText("接收到消息,更改UI");//經過Handler通知主線程更新UI
        }
        return false;
    }
});
new Thread() {
    @Override
    public void run() {
        super.run()
        Message msg = new Message();
        msg.what = 1;
        mHandler.sendMessage(msg);
    }
}.start();
複製代碼

這裏能夠看到,Handler實現了消息的傳出、消息的接收與處理,其實在post(Runnable)方法中,Runnable對象自己也是做爲一個消息傳出的,再次回顧Handler的概念:code

Handler主要用於異步消息的處理:當發出一個消息以後,首先進入一個消息隊列,發送消息的函數即刻返回,而另一個部分在消息隊列中逐一將消息取出,
而後對消息進行處理,也就是發送消息和接收消息不是同步的處理。 這種機制一般用來處理相對耗時比較長的操做。 
複製代碼

咱們知道了Handler是一個關於消息異步處理的任務機制,對於異步和同步,舉個例子說明對象

  • 同步處理:買傢俱→在商場選擇好傢俱→等待工人裝車→送到家中安裝傢俱→處理其餘事物
  • 異步處理:買傢俱→在網上買好傢俱→等待過程當中處理其餘事物→傢俱送到安裝傢俱

能夠看出,異步操做最大的特色是,不會阻礙調用者的工做,無需等待前一個操做作完才作下一個操做,對於耗時的操做,使用異步來處理是很是有必要的。

那麼在進行異步操做的過程當中,須要一個消息的傳遞者來指導各部分進行操做,在剛纔網購的例子裏,這個傳遞者是網上商城,而在Android的UI處理中,這個消息傳遞者就是Handler。

其餘一些Handler的使用方法

  • handler.post()
  • handler.postDelayed()
  • handler.sendMessage();
  • handler.sendEmptyMessage();
  • handler.removeCallback(runnable)
  1. AsyncTask異步任務的使用

    前面介紹了Handler+Thread進行異步消息處理,Android對此有封裝一個更好用的組件——AsyncTask。原理是相同的,但相比Handler+Thread更加簡單易用。

    使用時首先須要構建AsyncTask子類的泛型參數,AsyncTask<Params,Progress,Result>是一個抽象類,一般用於被繼承,繼承AsyncTask須要指定以下三個泛型參數:

    • Params:啓動任務時輸入的參數類型.
    • Progress:後臺任務執行中返回進度值的類型.
    • Result:後臺任務執行完成後返回結果的類型.

    在構建AsyncTask子類主要有以下幾個回調方法:

    • doInBackground:必須重寫,異步執行後臺線程要完成的任務,耗時操做將在此方法中完成.
    • onPreExecute:執行後臺耗時操做前被調用,一般用於進行初始化操做.
    • onPostExecute:當doInBackground方法完成後,系統將自動調用此方法,並將doInBackground方法返回的值傳入此方法.經過此方法進行UI的更新.
    • onProgressUpdate:當在doInBackground方法中調用publishProgress方法更新任務執行進度後,將調用此方法.經過此方法咱們能夠知曉任務的完成進度.
相關文章
相關標籤/搜索