(3)onProgressUpdate(Progress... values)
在 UI 线程上工作,会在 doInBackground() 中调用 publishProgress(Progress) 方法后执行,此方法用于在后台计算仍在执行时(也就是 doInBackgound() 还在执行时)将计算执行进度通过 UI 显示出来 。例如,可以通过动画进度条或显示文本字段中的日志 , 从而方便用户知道后台任务执行的进度 。
(4)onPostExecute(Result result)
在 UI 线程上工作,在任务执行完毕(即 doInBackground(Result) 执行完毕)并将执行结果传过来的时候工作 。
使用规则:
(1)AsyncTask 是个抽象类,所以要创建它的子类实现抽象方法
(1)AsyncTask 类必须是在 UI 线程中被加载,但在Android 4.1(API 16)开始,就能被自动加载完成 。
(2)AsyncTask 类的实例对象必须在 UI 线程中被创建 。
(3)execute() 方法必须是在 UI 线程中被调用 。
(4)不要手动调用方法 onPreExecute()、onPostExecute()、doInBackground()、onProgressUpdate()
(5)任务只能执行一次(如果尝试第二次执行,将抛出异常) 。即一个AsyncTask对象只能调用一次execute()方法 。
原理:
其源码中原理还是 Thread 与 Handler 的实现 , 其包含 两个线程池 , 一个 Handler,如下所示:
名称类型作用
SERIAL_EXECUTOR线程池分发任务,串行分发,一次只分发一个任务
THREAD_POOL_EXECUTOR线程池执行任务,并行执行,执行的任务由 SERIAL_EXECUTOR 分发
InternalHandlerHandler负责子线程与主线程的沟通,通知主线程做 UI 工作
一方面减少了每个并行任务独自建立线程的开销,另一方面可以管理多个并发线程的公共资源,从而提高了多线程的效率 。所以ThreadPoolExecutor比较适合一组任务的执行 。Executors利用工厂模式对ThreadPoolExecutor进行了封装 。
Executors提供了四种创建ExecutorService的方法,他们的使用场景如下:
1. Executors.newFixedThreadPool()
创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化 。
当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭 。当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来 。
只有核心线程并且不会被回收,能够更加快速的响应外界的请求 。
2. Executors.newCachedThreadPool()
创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时,它可以灵活的添加新的线程,而不会对池的长度作任何限制
线程数量不定的线程池,只有非核心线程,最大线程数为 Integer.MAX_VALUE 。当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务,否则利用空闲的线程来处理新任务 。线程池中的空闲线程具有超时机制,为 60s 。
任务队列相当于一个空集合,导致任何任务都会立即被执行,适合执行大量耗时较少的任务 。当整个线程池都处于限制状态时,线程池中的线程都会超时而被停止 。
3. Executors.newScheduledThreadPool()
创建一个定长的线程池 , 而且支持定时的以及周期性的任务执行,类似于Timer 。
非核心线程数没有限制,并且非核心线程闲置的时候立即回收,主要用于执行定时任务和具有固定周期的重复任务 。
4. Executors.newSingleThreadExecutor()
创建一个单线程化的executor,它只创建唯一的worker线程来执行任务
只有一个核心线程,保证所有的任务都在一个线程中顺序执行,意义在于不需要处理线程同步的问题 。
- “海马体”长度不到10厘米 竟能偷走人类的记忆力
- 科学家揭秘:人类基因是肢体再生的关键
- 娜迦毒蛇,不是蛇而是世界上最辣的辣椒
- 世界最强十大航母:美航母还能领先多少年?
- 地球上的生物为何要依赖氧气生存?氧气是怎么产生的
- 大脑的奥秘,科学揭秘人类大脑如何一心二用!
- 破解挑战者号背后的五大惊天谜团?
- 形容自己再做也得不到重视的成语
- 形容一次又一次的发生的成语
- 形容声音吵很烦躁的成语