Android-Daily-Interview icon indicating copy to clipboard operation
Android-Daily-Interview copied to clipboard

2019-04-15:AsyncTask的优点和缺点?

Open FeatherHunter opened this issue 6 years ago • 9 comments

FeatherHunter avatar Apr 14 '19 15:04 FeatherHunter

优点:使用方便,然后没了 缺点:在各版本系统差异极大,比如1.6时只能串行执行,2.1时改成并行执行,3.0默认又改成了串行,想要并行执行需要使用默认的线程池;5.1以下AsyncTask只能在主线程开启,4.x(具体版本记不清了)以下初始化(指执行时)也必须在主线程;官方文档上说onPreExecute方法是在主线程中执行的,但是查看源码发现竟然是在execute()里就执行了; 所以自定义一个比较好

canyie avatar Apr 15 '19 03:04 canyie

优点:AsyncTask操作简单,轻便,适用简单的异步操作。 缺点:存在新开大量线程,消耗系统资源的风险

chenqi5256969 avatar Apr 21 '19 03:04 chenqi5256969

优点:使用方便,既可以执行串行任务,也可以执行并行任务 缺点:默认使用串行任务执行效率低,不能充分利用多线程加快执行速度;如果使用并行任务执行,在任务特别多的时候会阻塞UI线程获得CPU时间片,后续做线程收敛需要自定义AsynTask,将其设置为全局统一的线程池,改动量比较大

risechen avatar Apr 24 '19 10:04 risechen

有点:方便 缺点:不可控制

liuyongyi0110 avatar May 23 '19 06:05 liuyongyi0110

AsyncTask的实现原理: 1.AsyncTask是一个抽象类,主要由Handler+2个线程池构成,SERIAL_EXECUTOR是任务队列线程池,用于调度任务,按顺序排列执行,THREAD_POOL_EXECUTOR是执行线程池,真正执行具体的线程任务。Handler用于工作线程和主线程的异步通信。

2.AsyncTask<Params,Progress,Result>,其中Params是doInBackground()方法的参数类型,Result是doInBackground()方法的返回值类型,Progress是onProgressUpdate()方法的参数类型。

3.当执行execute()方法的时候,其实就是调用SERIAL_EXECUTOR的execute()方法,就是把任务添加到队列的尾部,然后从头开始取出队列中的任务,调用THREAD_POOL_EXECUTOR的execute()方法依次执行,当队列中没有任务时就停止。

4.AsyncTask只能执行一次execute(params)方法,否则会报错。但是SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所以可以形成队列。

Q:AsyncTask只能执行一次execute()方法,那么为什么用线程池队列管理 ? 因为SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所有的AsyncTask实例都共享这2个线程池,因此形成了队列。

Q:AsyncTask的onPreExecute()、doInBackground()、onPostExecute()方法的调用流程? AsyncTask在创建对象的时候,会在构造函数中创建mWorker(workerRunnable)和mFuture(FutureTask)对象。 mWorker实现了Callable接口的call()方法,在call()方法中,调用了doInBackground()方法,并在最后调用了postResult()方法,也就是通过Handler发送消息给主线程,在主线程中调用AsyncTask的finish()方法,决定是调用onCancelled()还是onPostExecute(). mFuture实现了Runnable和Future接口,在创建对象时,初始化成员变量mWorker,在run()方法中,调用mWorker的call()方法。 当asyncTask执行execute()方法的时候,会先调用onPreExecute()方法,然后调用SERIAL_EXECUTOR的execute(mFuture),把任务加入到队列的尾部等待执行。执行的时候调用THREAD_POOL_EXECUTOR的execute(mFuture).

siren4 avatar Sep 03 '19 09:09 siren4

所有的asyctask 共享 两个线程池 一个用来排队 一个用来执行任务 asyctask中的任务默认是串行的,但是可以通过配置实现 并行 默认串行导致一个问题 asyctask只能用来处理 短暂的任务 非常耗时的任务请使用线程池,否则会过长等待

manondidi avatar Jan 19 '20 04:01 manondidi

优点: 方便实现异步操作和UI的更新 不需要能过handle和线程组合进行异步操作和UI更新 缺点 不同的多耗时操作时 要创建不同的AsyncTask这样搞得很乱很复杂 复用性不是那么高

mlinqirong avatar Dec 14 '21 10:12 mlinqirong

补充一个链接,我觉得说得不错的:http://www.voycn.com/article/asynctaskdequexianhezhuyishixiang

wyvector avatar Aug 24 '23 02:08 wyvector

Deprecated Use the standard java.util.concurrent or Kotlin concurrency utilities instead.

b1tb1t avatar Jan 25 '24 02:01 b1tb1t