這是 Android 性能模式第五季的第四集,從本期開始我會修改一下之前的規(guī)則,不再一句英文一句中文對應(yīng),而是先看完整個視頻,邊看邊翻譯,從而整理出重要的知識點。
盡量縮短別人看文章花費的時間,而大量工作我做就好了,就像我們寫代碼一樣, 封裝細節(jié)后直接提供對方使用。
本期視頻地址:
AsyncTask 讓我們又愛又恨(不過現(xiàn)在好像很少有人還會用它了吧),不過作為 Android 提供的工具類,它確實提供了一些簡單的使用方法,但如果如果使用不當(dāng),可能一不小心會傷害我們 App 的性能,比如內(nèi)存泄漏。
為什么會有 AsyncTask?我們都會遇到類似的場景,比如我解碼圖片,這確實會花費一些時間,所以我們會選擇在后臺線程進行,然后任務(wù)結(jié)束后在主線程更新 UI,如果有很多這種場景,那么我們不用每次都寫一遍上面的代碼,我們提出公共部分寫在一起就可以了,所以 AsyncTask 就誕生了(不過一個 AsyncTask 實例只能執(zhí)行一次)。
AsyncTask 為我們提供了一些簡單易用的方法,比如當(dāng)我們使用的它時候,最常用的三個方法就是,下面圖中的方法,因為這就已經(jīng)完全可以讓我們完成一個基本的任務(wù),我之前也寫過關(guān)于 AsyncTask 的學(xué)習(xí)筆記,地址如下:
雖然我們可以通過重寫上面三個方法完成一個簡單的 AsyncTask 但你還是需要小心,因為有些細微的問題你需要注意,不然我可能會比較頭疼。
接下來,會從三個方面說一下會有哪些小問題需要注意。
首先,我們需要注意 3.2 之后所有 AsyncTask 的任務(wù)都默認順序執(zhí)行,如果你同時開始了20個任務(wù),那么 AsyncTask 會按照順序一個個執(zhí)行任務(wù)。
不過我們可以通過通過 executeOnExecutor() 指定執(zhí)行任務(wù)時的線程池,從而實現(xiàn)所有任務(wù)并行執(zhí)行,下過如下圖:
第二問題是 cancel(), 看上去它的作用好像是取消一個任務(wù),但是實際上要配合 isCancelled() 使用,我們通過 AsyncTask 對象調(diào)用 cancel(),并在 doInBackground() 中使用 isCancelled(),代碼如下:
So,我們是通過 isCancelled() 判斷是否退出,從而決定是否停止任務(wù),不過當(dāng)我們?nèi)∠蝿?wù)后,我們在主線程回調(diào) onCancelled() 而不是 onPostExecute()。
最后一點,也是最關(guān)鍵的一點,就是當(dāng)我們 AsyncTask 作為普通內(nèi)部類使用時,從而引起內(nèi)存泄漏的問題。因為內(nèi)部類會隱式的持有外部 Activity 的引用,從而使得 Activity 無法被正常回收,直到 AsyncTask 執(zhí)行完任務(wù)。
在視頻結(jié)尾處,又介紹到了這些類,Android 確實給我們提供了一些不錯的工具類,當(dāng)我們在使用的過程中更應(yīng)該去考慮,它們能幫我解決什么問題,又會帶來問題或者隱患,所以不只是使用它們,而是應(yīng)該搞懂它們的原理,這樣才能更好地為我們所有。
如果有機會你其實你也可以去看看官方的視頻,挺有趣的,不是么?