(1)AsyncTask 4大回调方法的执行线程
doInBackground
publicProgress
preExecute
postExectue
通常我们的理解是:
doInBackground :异步线程
publicProgress :主线程
preExecute:主线程
postExectue:主线程
但实际上,如果你真这么想,你可得当心了,因为由于安卓系统的Bug,这些方法的执行线程未必如你想的那样。
1. preExecute 和你调用AsyncTask.execute()在同一个线程
这也意味着,如果你在非UI线程里面调用execute()话,在preExecute中执行UI更新操作,很可能会导致异常
2. postExectue, publicProgress使用的是sHandler初始化绑定的线程
通常情况下的安卓系统都会在主线程中加载AsyncTask类,这样sHandler默认会绑定到主线程上,
那么postExectue和publicProgress默认将在主线程中执行,这并没有什么问题。
但是,假设系统有bug,它不在主线程中初始化AsyncTask,那么postExectue中执行某些UI操作将会导致异常。
(你可以自己实现一个AsyncTask,然后在非UI线程中加载它,然后看看各个方法的执行对应线程)
3 doInBackground 的执行线程
这个线程是线程池为你分配的一个线程,也就是说它默认情况下是没有进行办法初始化Handler的。
这就意味着,在极端情况下,这4个回调方法可能在3个不同的线程中执行,并且还都不是主线程。
(2) AsyncTask 线程阻塞
在doInBackground 执行网络拉取操作是错误的写法!!
因为在安卓3.0 之后,AsyncTask的默认执行器是顺序执行的。
它会一个一个的执行你的任务,而不是并发的执行这些任务。
除了第一次,之后scheduleNext(); 一定在r.run();后执行,
所以即使是并发线程池,也就一个Runnable执行而已。
所以,网络拉取操作可能阻塞其他AsyncTask.不建议在doBackground中执行。
如果你一定要这么干,请为AsyncTask分配一个额外的执行器。
或者使用v4包里面的AsyncTask.