调用AsyncTask.execute()后doInBackground()方法没有立即执行

今天在使用AsyncTask查询数据库时发现了一个问题,经常会过了好几秒才返回查询到的结果。这个问题导致了进入页面时activity没有获取到数据库的数据,从而出现假死的状态。

通过debug发现调用AsyncTask.execute()后doInBackground执行的时间时快时慢,我们点击进入execute方法的源码看一下:
image.png

发现调用了executeOnExecutor()方法并且传入了两个参数,我们重点看第一个参数:
image.png

发现AsyncTask其实是把任务交给线程池来执行的,当我们调用execute方法时默认传入了一个SerialExecutor线程池对象来执行任务,从名字上可以看出这个线程池是串行的,也就是说如果之前我们使用了AsyncTask来执行其他任务,当前一个任务没有执行完时我们刚才执行的任务是需要等待前一个任务执行完成后才能执行的,这也就解释了为什么查询数据库操作的时候时快时慢。知道了原因就好解决问题了,系统还给我们提供了另一个执行AsyncTask的Api就是execute调用的executeOnExecutor()方法,我们在使用时需要传入一个线程池。现在只需要使用.executeOnExecutor(Executors.newCachedThreadPool())就可以解决线程串行带来的等待时间过长的问题。最后附上AsyncTask在各个版本的演变史,更方便理解execute()方法。

在1.6(Donut)之前:
在第一版的AsyncTask,任务是串行调度。一个任务执行完成另一个才能执行。由于串行执行任务,使用多个AsyncTask可能会带来有些问题。所以这并不是一个很好的处理异步(尤其是需要将结果作用于UI试图)操作的方法。
从1.6到2.3(Gingerbread):
后来Android团队决定让AsyncTask并行来解决1.6之前引起的问题,这个问题是解决了,新的问题又出现了。很多开发者实际上依赖于顺序执行的行为。于是很多并发的问题蜂拥而至。
3.0(Honeycomb)到现在:
好吧,开发者可能并不喜欢让AsyncTask并行,于是Android团队又把AsyncTask改成了串行。当然这一次的修改并没有完全禁止AsyncTask并行。你可以通过设置executeOnExecutor(Executor)来实现多个AsyncTask并行。

你可能感兴趣的:(调用AsyncTask.execute()后doInBackground()方法没有立即执行)