Android API中有提到,AsyncTask非常适合短时间异步操作。如果要执行长时间操作,最好使用线程池Executor:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
也许很多人会有疑问,这是为什么呢?后来我在stackoverflow上找到了一个比较好的回答。
提到了两个原因:
- AsyncTask的生命周期没有跟Activity的生命周期同步
- 容易内存泄露
AsyncTask和Activity的生命周期
如果你在一个Activity中创建了一个AsyncTask,你旋转了屏幕,这个Activity将会被销毁并且会重新创建一个新的实例。但是AsyncTask没有销毁,它将会继续执行直到完成。当它执行完成后,它实际上是更新了上一个已经不存在的Activity,如果你原本想在onPostExecute()中更新UI的话,这时的AsyncTask将不会更新新的Activity,并且这个操作会引发一个异常:java.lang.IllegalArgumentException。
如果你是想要在onPostExecute()中关闭一个dialog,则会发生:java.lang.IllegalArgumentException: View not attached to window manager(前提是你忘记在Activity的onStop()中忘记dismiss)。不仅如此,还会在show()的调用出抛出一个lead window的异常:
但那个回答中提到,如果你使用了findVIewById来提取Activity中的view也会发生异常,但经过测试没发现。
- Activity com.xxx.XXXActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{5350b3f4 V.E..... R....... 0,0-729,192} that was originally added here