標籤:解析 ons [] img 非同步任務 .com 之間 等等 存在
什麼是非同步任務?
非同步任務就是開一個子線程,然後讓它去跑,它跑完了就會回來告訴你說,它跑完了,這是結果。這和Java中的回調差不多。我們在OKHttp中很長見到的 onSuccess() 和 onError() 這些都是回呼函數。當然這篇博文不討論這些回調,只討論Android中內建的非同步任務。
Android官方在4.0以後的版本系統裡面就禁止在主線程訪問網路了。
解決這個的唯一的辦法就是開一個子線程,子線程去訪問網路。剛好,google 給 Android 寫了一個方便廣大各位編程人員使用的工具類,AsyncTask。下面就來看看這個非同步任務怎麼用?
首先,寫一個類,繼承 AsyncTask,實現 AsyncTask 比較簡單,必須實現的只有一個方法,那就是doInBackground() 其他都可以不需要去實現的,但通常我們使用的時候都不僅僅是重寫 doInBackground() 還有其他函數與之相配合。下面就來看看這幾個函數分別是什麼,各自有什麼作用。
doInBackground()
這方法是在子線程中執行的,也是裡面這麼多方法中唯一一個是子線程中執行的,這裡一般做的是非同步任務要做的事情(也就是耗時的任務),例如訪問網路等,都寫在這個方法裡面。
onPreExecute()
這個方法是在UI線程中執行的,看方法名也知道個大概了,這個方法是在 doInBackground() 之前調用,也就是非同步任務的準備工作等,例如:訪問網路前彈出進度條,收集要傳遞的參數等等。。。
onPostExecute()
這個和前面的 onPreExecute() 相對應。它是在 doInBackground() 之後執行的,同時也是在UI線程中執行的。這裡一般用來做非同步任務執行完畢後的操作,例如,Json解析(有些JSON大一點的也會在doInbackground()解析),更新列表,UI上的文字圖片等等。。。
onProgressUpdate()
既然有前有後了,那麼就差一個中間的了。沒錯,這個方法就是在 doInBackground() 執行的過程中回調的一個方法。這個有什麼用呢?存在就是有道理的,例如我們下載的時候一般都會告訴你下載了百分之多少,對吧。還有,這個函數也是在UI線程中執行的。
另外還有其他的幾個函數 onCancel() 等,這些都不怎麼常用,可以稍做理解就可以。沒必要深入的去看。
泛型和方法的傳回值、參數是啥意思?
函數搞懂什麼作用的了,仔細看看,我上面的都沒有參數的,實際上是有參數的,對,是有,而且參數很重要。而且,我們繼承 AsyncTask 的時候還有 3 個泛型的參數,這又是什嗎?現在就來看看泛型的參數和方法的參數以及方法的傳回值分別是什麼意思,並且分別有什麼聯絡?
三個泛型分別是:Params, Progress, Result
Params:故名思議,是參數,也就是外部傳遞進來的參數,也就是我們執行execute()這個方法傳遞進來的,同時,可以看到,我們這個泛型和 doInBackground() 所接受的參數的類型是一致的。
Progress:這個參數也很好理解,就是進度,也就是執行過程回調的,我們可以看到 onProgressUpdate() 接收的參數的類型和這個是一致的,沒錯。就是這樣
Result:這個參數也知道什麼意思了,結果,也就是子線程的執行的結果,也是 doInBackground() 的傳回值的類型,同時也是 onPostExecute() 所接收的參數的類型。
下面來看看參數之間的關係:
先看紅色的箭頭,紅色的箭頭表示規定的參數的類型的限制,也就是繼承AsyncTask的時候的這 3 個參數類型其實限制的是 doInBackground 、 onProgressUpdate 、onPostExecute 這三個函數的接收的參數的類型和傳回值的類型。
再看綠色的箭頭,綠色的箭頭表示資料的傳遞的過程。從一開始的execute的時候傳遞的參數,其實是傳遞到 doInBackground 裡面的,doInBackground 返回的參數,其實是傳遞到 onPostExecute 。
以上兩點是必須要搞清楚的,也是初學者比較難理解的,至於可變參數,初學者可以直接理解成數組,例如 doInBackground 接收的是 String... 你就可以理解成 String[] ,而取值的時候也是以數組的方式進行取值,更多可變參數的內容點擊這裡。
下面我們來通過一個例子來看看實際怎麼使用?
代碼沒什麼,就是通過日誌去跟蹤整個 AsyncTask 的執行的過程。
下面來看看 AsyncTask 的使用和列印的日誌:
使用的話,這裡直接就 new 了一個非同步任務,然後直接調用 execute() 去執行了。
最後來分析分析日誌,
onPreExecute() 確實是在 doInBackground() 之前執行,同時我們看傳遞進去的參數,傳遞進去的參數,分別是 “123” 、“456”,這裡也分別取出來了。然後是執行子線程裡面的代碼,代碼很簡單,每休眠 1 秒就往 onProgressUpdate() 發送一次資料,這也可以通過日誌看到,每次接收到的參數也分別列印出來,和我們發出去的參數是一致的。最後執行完了,執行完了返回的是 “true”,日誌最後一行列印出來的也是true,這也證實了我們前面圖上綠色箭頭,參數的傳遞的過程。
整個 AsyncTask 到此解析完畢,下面還有幾點需要說明的。
1、AsyncTask只能執行一次,不能執行多次。
2、一旦執行,不可取消,網上說的可以取消的都是騙子,都是騙子,不能取消,解決的唯一途徑就是對這次請求的資料不做處理,也就是忽略資料,當作這次沒請求,這就需要搞一個標誌位去記住是否處理請求回來的資料。
Android-非同步任務-AsyncTask