# 读 Android 开发艺术探索 &12
2017-02-06 12:02
260 查看
关键词:线程 / 线程池 / AsyncTask / IntentService / Handler
本次笔记主要梳理了 Android 的线程与线程池的相关知识点。从用途上来说,线程分为 主线程 和 子线程,主线程处理和界面相关的事情,子线程则往往用于处理执行耗时的操作。除了 Thread 本身之外,扮演线程角色的还有很多,比如:AsyncTask、IntentService、HandlerThread…
对于 AsyncTask 来说,它的底层用到了线程池,对于 IntentService 和 HandlerThread 来说,它们的底层则直接使用了线程。当系统中存在大量的线程时,系统会通过时间片轮转的方式调度每一个线程,线程不可能做到绝对的并行,正确的做法是采用线程池,一个线程池会缓存一定数量的线程,通过线程池就可以避免因为频繁创建和销毁线程所带来的系统开销。Android 中的线程池来源于 Java,主要通过 Executor 来派生特定类型的线程池,不同种类的线程池具有各自的特性。
AsyncTask 封装了 Thread 和 Handler,通过 AsyncTask 可以更加方便地执行后台任务以及在主线程中访问 UI,但是 AsyncTask 并不适合进行特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池;
AsyncTask 的类必须在主线程中加载,意味着第一次访问 AsyncTask 必须发生在主线程;
AsyncTask 的对象必须在主线程中创建;
execute 方法必须在 UI 线程中调用;
不要程序中直接调用 onPreExecute()、onPostExecute()、doInBackground 和 onProgressUpdate 方法;
一个 AsyncTask 对象只能执行一次,即只能调用一次 execute 方法,否则会报运行时异常;
普通 Thread 主要用于 run 方法中执行一个耗时任务,而 HandlerThread 在内部创建了消息队列,外界需要通过 Handler 的消息方式来通知 HandlerThread 执行一个具体的任务;
一个具体的使用场景就是:IntentService。每执行一个后台任务就必须启动一次 IntentService,而 IntentService 内部则通过消息的方式向 HandlerThread 请求执行任务,Handler 中的 Looper 是顺序处理消息的,意味着 IntentService 也是顺序执行后台任务的;
重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销;
能有效的控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象;
能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能;
线程池的分类:
FixedThreadPool
它是一种进程数量固定的线程池,当线程处于空闲的时候,它们并不会被回收,除非线程池被关闭了;
CacheThreadPool
它是一种线程数量不定的线程池,它只有非核心线程,并且其最大的线程数为 Integer.MAX_VALUE;
ScheduledThreadPool
它的核心线程数量是固定的,而非核心线程的数量没有限制,并且当非核心线程闲置的时候会被立即回收;
SingleThreadExecutor
此类线程池中只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行;
End.
Note by HF.
Learn from 《Android 开发艺术探索》
本次笔记主要梳理了 Android 的线程与线程池的相关知识点。从用途上来说,线程分为 主线程 和 子线程,主线程处理和界面相关的事情,子线程则往往用于处理执行耗时的操作。除了 Thread 本身之外,扮演线程角色的还有很多,比如:AsyncTask、IntentService、HandlerThread…
对于 AsyncTask 来说,它的底层用到了线程池,对于 IntentService 和 HandlerThread 来说,它们的底层则直接使用了线程。当系统中存在大量的线程时,系统会通过时间片轮转的方式调度每一个线程,线程不可能做到绝对的并行,正确的做法是采用线程池,一个线程池会缓存一定数量的线程,通过线程池就可以避免因为频繁创建和销毁线程所带来的系统开销。Android 中的线程池来源于 Java,主要通过 Executor 来派生特定类型的线程池,不同种类的线程池具有各自的特性。
1. AsyncTask #
AsyncTask 是一个轻量级的异步任务类,可以在线程池中执行后台任务,然后执行的进度和最终的结果传递给主线程并在主线程中更新 UI;AsyncTask 封装了 Thread 和 Handler,通过 AsyncTask 可以更加方便地执行后台任务以及在主线程中访问 UI,但是 AsyncTask 并不适合进行特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池;
AsyncTask 的类必须在主线程中加载,意味着第一次访问 AsyncTask 必须发生在主线程;
AsyncTask 的对象必须在主线程中创建;
execute 方法必须在 UI 线程中调用;
不要程序中直接调用 onPreExecute()、onPostExecute()、doInBackground 和 onProgressUpdate 方法;
一个 AsyncTask 对象只能执行一次,即只能调用一次 execute 方法,否则会报运行时异常;
2. HandlerThread #
HandlerThread 继承了 Thread,是一种可以使用 Handler 的 Thread;普通 Thread 主要用于 run 方法中执行一个耗时任务,而 HandlerThread 在内部创建了消息队列,外界需要通过 Handler 的消息方式来通知 HandlerThread 执行一个具体的任务;
一个具体的使用场景就是:IntentService。每执行一个后台任务就必须启动一次 IntentService,而 IntentService 内部则通过消息的方式向 HandlerThread 请求执行任务,Handler 中的 Looper 是顺序处理消息的,意味着 IntentService 也是顺序执行后台任务的;
3. Android 线程池 #
线程池的好处:重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销;
能有效的控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象;
能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能;
线程池的分类:
FixedThreadPool
它是一种进程数量固定的线程池,当线程处于空闲的时候,它们并不会被回收,除非线程池被关闭了;
CacheThreadPool
它是一种线程数量不定的线程池,它只有非核心线程,并且其最大的线程数为 Integer.MAX_VALUE;
ScheduledThreadPool
它的核心线程数量是固定的,而非核心线程的数量没有限制,并且当非核心线程闲置的时候会被立即回收;
SingleThreadExecutor
此类线程池中只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行;
End.
Note by HF.
Learn from 《Android 开发艺术探索》
相关文章推荐
- # 读 Android 开发艺术探索 &10
- # 读 Android 开发艺术探索 &2
- # 读 Android 开发艺术探索 &3
- # 读 Android 开发艺术探索 &6
- # 读 Android 开发艺术探索 &8
- # 读 Android 开发艺术探索 &11
- # 读 Android 开发艺术探索 &13
- # 读 Android 开发艺术探索 &7
- # 读 Android 开发艺术探索 &4
- # 读 Android 开发艺术探索 &1
- # 读 Android 开发艺术探索 &5
- 任玉刚【Android开发艺术探索】读后笔记四
- Android开发艺术探索学习-IPC之Binder(一)
- 读书笔记-Android开发艺术探索-第12章-Bitmap的加载和Cache
- 任玉刚【Android开发艺术探索】读后笔记一
- 读书笔记-Android开发艺术探索-第11章-Android的线程和线程池
- 【读书笔记】【Android开发艺术探索】第10章 Android 的消息机制
- 【读书笔记】Android开发艺术探索
- Android开发艺术探索学习-View的事件分发机制(二)
- Android开发艺术探索学习-View的滑动