作者:囧尼
Lifecycle
所以我們必須要確認在destroyed Activity的同時,有去取消 (cancel) AsyncTask 掉。呼叫cancel(boolean mayInterruptRunning)來cancel這個task,這個boolean值為true的話,代表當前的task應該立即被中斷,反之則允許處理完當前事務後結束。如果在doInBackground()中有使用道loop的話,建議可以每次呼叫isCancelled()方法來避免掉多餘的處理。
Does cancel really work?
這個答案是有時候,如果你參數的boolean值丟false的話,它會繼續處理至結束為止,但可以避免隨後的onPostExecute()被呼叫到。如果是丟true的話,是不是一定就能中段當前處理而結束呢?也不盡然,因為有些是不能不中斷的操作如BitmapFactory.decodeStream()。
Memory leaks
Activity會保有AsyncTask的reference,但當Activity destroyed的時候,只要此Task還在執行,這reference還是存在,這會導致memory leak的問題發生。
Losing your results
當我們手機進行橫式和直式的改變時,此時Activity會重新創建,但在這之前所執行的AsyncTask卻會因會找不到reference而沒辦法傳回使用者想要的結果。為了解決這個問題,請將AsyncTask的reference放在在global holder中,可以利用Activity.onRetainNonConfigurationInstance 以及 Fragment.setRetainedInstance(true)
Serial or parallel?
到底AsyncTask是照順序來執行還是平行的處理呢?看看下面這段程式碼
究竟Task1和Task2是同時跑,還是Task2會等Task1值行完後再來執行呢?
這取決於API level(因為目前開發顯少用3.0以前的版本,所以之前的就不提)。
Android 3.0以後,Task2是會等待Task1執行完成在去處理的,但如果我又想讓這兩個任務同時執行呢?可以透過 AsyncTask的method executeOnExecutor(Executor)來達成
下面這段程式碼可以用來控制在不同的API版本它都是平行處理這些task的
結論
究竟我們是不是這麼需要AsyncTask呢?其實不然,但如果要使用,要切記這些可能發生的問題。下次在使用這些方便的class同時,也別忘記它們便力的背後可能藏有ㄧ些需要注意的地方。
此外,還有另一個class Loaders ,這個也是能完成在背景處理的需求,有需要的人可以看看。
Reference :
沒有留言 :
張貼留言